您的位置:首页 > 移动开发 > Android开发

实现android左右滑动效果:ViewFlipper、ViewPager、HorizontalScrollView

2013-04-01 11:28 921 查看
http://blog.csdn.net/myshapozi/article/details/7444643

ViewFlipper

本例来源:www.ideasandroid.com 原文: http://www.ideasandroid.com/archives/414

使用ViewFlipper来将您要来回拖动的View装在一起,然后与GestureDetector手势识别类来联动,确定要显示哪个View,加上一点点动画效果即可。比如当手指向左快速滑动时跳转到上一个View,手指向右快速滑动时跳转到下一个View,本例中使用图片作为各个View的页面,实现左右快速滑动显示不同的图片。

首先来看看我们的layout,如下所示:

1
<
LINEARLAYOUT
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:orientation
=
"vertical"
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
>
2
    
<
VIEWFLIPPER
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
android:layout_below
=
"@+id/CockpitLayout"
android:id
=
"@+id/flipper"
>
3
        
<
INCLUDE
android:id
=
"@+id/firstlayout"
layout
=
"@layout/first"
>
4
        
<
INCLUDE
android:id
=
"@+id/secondlayout"
layout
=
"@layout/second"
>
5
        
<
INCLUDE
android:id
=
"@+id/thirdlayout"
layout
=
"@layout/third"
>
6
        
<
INCLUDE
android:id
=
"@+id/fourthlayout"
layout
=
"@layout/fourth"
>
7
    
</
INCLUDE
></
INCLUDE
></
INCLUDE
></
INCLUDE
></
VIEWFLIPPER
>
8
</
LINEARLAYOUT
>
如上所示,在ViewFlipper中放置多个layout(接下来会在不同的layout中来回滑动),ViewFlipper在同一个页面就显示其中一个layout。

ViewFlipper中的四个layout很简单,我们就放置一张图片,如下所示:

 

1
<
LINEARLAYOUT
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
android:gravity
=
"center_vertical"
>
2
  
<
IMAGEVIEW
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:src
=
"@drawable/v1"
>
3
</
IMAGEVIEW
></
LINEARLAYOUT
>
接下来我们来看看Activity,我们的Activity需要实现两个接口OnGestureListener,OnTouchListener。具体的代码如下所示,代码中都有相应的注释,这里就不再详述。

001
package
 
com.ideasandroid.demo;
002
import
 
android.app.Activity;
003
import
 
android.os.Bundle;
004
import
 
android.view.GestureDetector;
005
import
 
android.view.MotionEvent;
006
import
 
android.view.View;
007
import
 
android.view.GestureDetector.OnGestureListener;
008
import
 
android.view.View.OnTouchListener;
009
import
 
android.view.animation.AccelerateInterpolator;
010
import
 
android.view.animation.Animation;
011
import
 
android.view.animation.TranslateAnimation;
012
import
 
android.widget.ViewFlipper;
013
public
 
class
 
ViewFlipperDemo 
extends
Activity
implements
OnGestureListener,OnTouchListener{
014
    
private
ViewFlipper mFlipper;
015
    
GestureDetector mGestureDetector;
016
    
private
int
mCurrentLayoutState;
017
    
private
static
final
int
 
FLING_MIN_DISTANCE =
100
;
018
    
private
static
final
int
 
FLING_MIN_VELOCITY =
200
;
019
 
 
020
    
@Override
021
    
public
void
onCreate(Bundle savedInstanceState) {
022
        
super
.onCreate(savedInstanceState);
023
        
setContentView(R.layout.main);
024
        
mFlipper = (ViewFlipper) findViewById(R.id.flipper);
025
        
//注册一个用于手势识别的类
026
        
mGestureDetector =
new
GestureDetector(
this
);
027
        
//给mFlipper设置一个listener
028
        
mFlipper.setOnTouchListener(
this
);
029
        
mCurrentLayoutState =
0
;
030
        
//允许长按住ViewFlipper,这样才能识别拖动等手势
031
        
mFlipper.setLongClickable(
true
);
032
    
}
033
 
 
034
    
/**
035
     
* 此方法在本例中未用到,可以指定跳转到某个页面
036
     
* @param switchTo
037
     
*/
038
    
public
void
switchLayoutStateTo(
int
switchTo) {
039
        
while
(mCurrentLayoutState != switchTo) {
040
            
if
(mCurrentLayoutState > switchTo) {
041
                
mCurrentLayoutState--;
042
                
mFlipper.setInAnimation(inFromLeftAnimation());
043
                
mFlipper.setOutAnimation(outToRightAnimation());
044
                
mFlipper.showPrevious();
045
            
}
else
{
046
                
mCurrentLayoutState++;
047
                
mFlipper.setInAnimation(inFromRightAnimation());
048
                
mFlipper.setOutAnimation(outToLeftAnimation());
049
                
mFlipper.showNext();
050
            
}
051
 
 
052
        
}
053
        
;
054
    
}
055
 
 
056
    
/**
057
     
* 定义从右侧进入的动画效果
058
     
* @return
059
     
*/
060
    
protected
Animation inFromRightAnimation() {
061
        
Animation inFromRight =
new
TranslateAnimation(
062
                
Animation.RELATIVE_TO_PARENT, +
1
.0f,
063
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
064
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
065
                
Animation.RELATIVE_TO_PARENT,
0
.0f);
066
        
inFromRight.setDuration(
500
);
067
        
inFromRight.setInterpolator(
new
AccelerateInterpolator());
068
        
return
inFromRight;
069
    
}
070
 
 
071
    
/**
072
     
* 定义从左侧退出的动画效果
073
     
* @return
074
     
*/
075
    
protected
Animation outToLeftAnimation() {
076
        
Animation outtoLeft =
new
TranslateAnimation(
077
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
078
                
Animation.RELATIVE_TO_PARENT, -
1
.0f,
079
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
080
                
Animation.RELATIVE_TO_PARENT,
0
.0f);
081
        
outtoLeft.setDuration(
500
);
082
        
outtoLeft.setInterpolator(
new
AccelerateInterpolator());
083
        
return
outtoLeft;
084
    
}
085
 
 
086
    
/**
087
     
* 定义从左侧进入的动画效果
088
     
* @return
089
     
*/
090
    
protected
Animation inFromLeftAnimation() {
091
        
Animation inFromLeft =
new
TranslateAnimation(
092
                
Animation.RELATIVE_TO_PARENT, -
1
.0f,
093
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
094
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
095
                
Animation.RELATIVE_TO_PARENT,
0
.0f);
096
        
inFromLeft.setDuration(
500
);
097
        
inFromLeft.setInterpolator(
new
AccelerateInterpolator());
098
        
return
inFromLeft;
099
    
}
100
 
 
101
    
/**
102
     
* 定义从右侧退出时的动画效果
103
     
* @return
104
     
*/
105
    
protected
Animation outToRightAnimation() {
106
        
Animation outtoRight =
new
TranslateAnimation(
107
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
108
                
Animation.RELATIVE_TO_PARENT, +
1
.0f,
109
                
Animation.RELATIVE_TO_PARENT,
0
.0f,
110
                
Animation.RELATIVE_TO_PARENT,
0
.0f);
111
        
outtoRight.setDuration(
500
);
112
        
outtoRight.setInterpolator(
new
AccelerateInterpolator());
113
        
return
outtoRight;
114
    
}
115
 
 
116
    
public
boolean
onDown(MotionEvent e) {
117
        
// TODO Auto-generated method stub
118
        
return
false
;
119
    
}
120
 
 
121
    
/*
122
     
* 用户按下触摸屏、快速移动后松开即触发这个事件
123
     
* e1:第1个ACTION_DOWN MotionEvent
124
     
* e2:最后一个ACTION_MOVE MotionEvent
125
     
* velocityX:X轴上的移动速度,像素/秒
126
     
* velocityY:Y轴上的移动速度,像素/秒
127
     
* 触发条件 :
128
     
* X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
129
     
*/
130
    
public
boolean
onFling(MotionEvent e1, MotionEvent e2,
float
velocityX,
131
            
float
velocityY) {
132
        
if
(e1.getX() - e2.getX() > FLING_MIN_DISTANCE
133
                
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
134
            
// 当像左侧滑动的时候
135
            
//设置View进入屏幕时候使用的动画
136
            
mFlipper.setInAnimation(inFromRightAnimation());
137
            
//设置View退出屏幕时候使用的动画
138
            
mFlipper.setOutAnimation(outToLeftAnimation());
139
            
mFlipper.showNext();
140
        
}
else
if
(e2.getX() - e1.getX() > FLING_MIN_DISTANCE
141
                
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
142
            
// 当像右侧滑动的时候
143
            
mFlipper.setInAnimation(inFromLeftAnimation());
144
            
mFlipper.setOutAnimation(outToRightAnimation());
145
            
mFlipper.showPrevious();
146
        
}
147
        
return
false
;
148
    
}
149
 
 
150
    
public
void
onLongPress(MotionEvent e) {
151
        
// TODO Auto-generated method stub
152
 
 
153
    
}
154
 
 
155
    
public
boolean
onScroll(MotionEvent e1, MotionEvent e2,
float
distanceX,
156
            
float
distanceY) {
157
        
return
false
;
158
    
}
159
 
 
160
    
public
void
onShowPress(MotionEvent e) {
161
        
// TODO Auto-generated method stub
162
 
 
163
    
}
164
 
 
165
    
public
boolean
onSingleTapUp(MotionEvent e) {
166
        
// TODO Auto-generated method stub
167
        
return
false
;
168
    
}
169
    
public
boolean
onTouch(View v, MotionEvent event) {
170
        
// 一定要将触屏事件交给手势识别类去处理(自己处理会很麻烦的)
171
        
return
mGestureDetector.onTouchEvent(event);
172
    
}
173
}
 

ViewPager
ViewPager的下载与安装

首先通过SDK Manager更新最新版android compatibility package, revision 3
更新后,在eclipse中工程上点击右键,选择android tools -> add compatibility library即可完成安装
实际上就是一个jar包,手工导到工程中也可
jar包所在位置是android-sdk-windows\extras\android\support\v4\android-support-v4.jar
至此准备环境已经ok
效果:


准备布局文件
main.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    <android.support.v4.view.ViewPager

        android:id="@+id/guidePages"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"/>

       

    <RelativeLayout  

        android:layout_width="fill_parent"  

        android:layout_height="wrap_content"  

        android:orientation="vertical" >

    <LinearLayout  

        android:id="@+id/viewGroup"  

        android:layout_width="fill_parent"  

        android:layout_height="wrap_content"  

        android:layout_alignParentBottom="true"  

        android:layout_marginBottom="30dp"  

        android:gravity="center_horizontal"  

        android:orientation="horizontal" >  

    </LinearLayout>  

    </RelativeLayout>

</FrameLayout>
item01.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    

    <ImageView  

        android:layout_width="fill_parent"  

        android:layout_height="fill_parent"  

        android:background="@drawable/feature_guide_0" >  

    </ImageView>

    

</LinearLayout>
item02.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    

    <ImageView  

        android:layout_width="fill_parent"  

        android:layout_height="fill_parent"  

        android:background="@drawable/feature_guide_1" >  

    </ImageView>

    

</LinearLayout>
item03.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    

    <ImageView  

        android:layout_width="fill_parent"  

        android:layout_height="fill_parent"  

        android:background="@drawable/feature_guide_2" >  

    </ImageView>

    

</LinearLayout>
item04.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    

    <ImageView  

        android:layout_width="fill_parent"  

        android:layout_height="fill_parent"  

        android:background="@drawable/feature_guide_3" >  

    </ImageView>

</LinearLayout>
 

 public class GuideViewDemoActivity extends Activity {

 

    private ViewPager viewPager;  

    private ArrayList<View> pageViews;  

    private ViewGroup main, group;  

    private ImageView imageView;  

    private ImageView[] imageViews; 

    

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        

        LayoutInflater inflater = getLayoutInflater();  

        pageViews = new ArrayList<View>();  

        pageViews.add(inflater.inflate(R.layout.item01, null));  

        pageViews.add(inflater.inflate(R.layout.item02, null));  

        pageViews.add(inflater.inflate(R.layout.item03, null));  

        pageViews.add(inflater.inflate(R.layout.item04, null));   

  

        imageViews = new ImageView[pageViews.size()];  

        main = (ViewGroup)inflater.inflate(R.layout.main, null);  

        

        // group是R.layou.main中的负责包裹小圆点的LinearLayout.  

        group = (ViewGroup)main.findViewById(R.id.viewGroup);  

  

        viewPager = (ViewPager)main.findViewById(R.id.guidePages);  

  

        for (int i = 0; i < pageViews.size(); i++) {  

            imageView = new ImageView(GuideViewDemoActivity.this);  

            imageView.setLayoutParams(new LayoutParams(20,20));  

            imageView.setPadding(20, 0, 20, 0);  

            imageViews[i] = imageView;  

            if (i == 0) {  

                //默认选中第一张图片

                imageViews[i].setBackgroundResource(R.drawable.page_indicator_focused); 

            } else {  

                imageViews[i].setBackgroundResource(R.drawable.page_indicator);  

            }  

            group.addView(imageViews[i]);  

        }  

  

        setContentView(main);  

  

        viewPager.setAdapter(new GuidePageAdapter());  

        viewPager.setOnPageChangeListener(new GuidePageChangeListener());  

    }

    

    /** 指引页面Adapter */

    class GuidePageAdapter extends PagerAdapter {  

       

        @Override  

        public int getCount() {  

            return pageViews.size();  

        }  

  

        @Override  

        public boolean isViewFromObject(View arg0, Object arg1) {  

            return arg0 == arg1;  

        }  

  

        @Override  

        public int getItemPosition(Object object) {  

            // TODO Auto-generated method stub  

            return super.getItemPosition(object);  

        }  

  

        @Override  

        public void destroyItem(View arg0, int arg1, Object arg2) {  

            // TODO Auto-generated method stub  

            ((ViewPager) arg0).removeView(pageViews.get(arg1));  

        }  

  

        @Override  

        public Object instantiateItem(View arg0, int arg1) {  

            // TODO Auto-generated method stub  

            ((ViewPager) arg0).addView(pageViews.get(arg1));  

            return pageViews.get(arg1);  

        }  

  

        @Override  

        public void restoreState(Parcelable arg0, ClassLoader arg1) {  

            // TODO Auto-generated method stub  

  

        }  

  

        @Override  

        public Parcelable saveState() {  

            // TODO Auto-generated method stub  

            return null;  

        }  

  

        @Override  

        public void startUpdate(View arg0) {  

            // TODO Auto-generated method stub  

  

        }  

  

        @Override  

        public void finishUpdate(View arg0) {  

            // TODO Auto-generated method stub  

  

        }  

    } 

    

    /** 指引页面改监听器 */

    class GuidePageChangeListener implements OnPageChangeListener {  

  

        @Override  

        public void onPageScrollStateChanged(int arg0) {  

            // TODO Auto-generated method stub  

  

        }  

  

        @Override  

        public void onPageScrolled(int arg0, float arg1, int arg2) {  

            // TODO Auto-generated method stub  

  

        }  

  

        @Override  

        public void onPageSelected(int arg0) {  

            for (int i = 0; i < imageViews.length; i++) {  

                imageViews[arg0]  

                        .setBackgroundResource(R.drawable.page_indicator_focused); 

                if (arg0 != i) {  

                    imageViews[i]  

                            .setBackgroundResource(R.drawable.page_indicator);  

                }  

            }

  

        }  

  

    }  

    

}

源码位置:

HorizontalScrollView
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: