Android 滑动切换页面 以及屏幕手势

本文转自:http://trinea.iteye.com/blog/1054786    

 http://blog.csdn.net/lonelyroamer/article/details/7558313

 

手机进入智能机时代,触摸屏也已成为主流之势,原来的手机按键也被屏幕点触取代,滑动屏幕操作则相对屏幕点击更能获得用户的青睐,习惯了各种浏览器的鼠标手势、pad等平板的切滑、类似iReader的软件丰富的手势后,是不是也想自己的软件能够用食指炫起来呢,下面就让我们来看看android的手势操作吧

 

先介绍下左右滑动切换Activity,对于复杂的手势原理一样,具体后述。

主要原理为监控触屏事件和手势事件,在触屏事件处理函数中调用手势事件处理函数,表示用户触屏后是否有手势操作,有则进行手势事件处理,大致分为四步

 

1、需要继承OnGestureListener和OnDoubleTapListener,如下:

Java代码 复制代码  收藏代码
  1. public class ViewSnsActivity extends Activity implements OnTouchListener, OnGestureListener  

这两个类分别是触屏监听器和手势监控器,具体可查看OnTouchListenerOnGestureListener

 

2、在添加mGestureDetector的定义,并在ViewSnsActivity的onCreate函数中加入其页面布局的setOnTouchListener事件

Java代码 复制代码  收藏代码
  1. GestureDetector mGestureDetector;  
  
Java代码 复制代码  收藏代码
  1. public void onCreate(Bundle savedInstanceState) {   
  2.         super.onCreate(savedInstanceState);   
  3.         setContentView(R.layout.view_sns_activity);   
  4.            
  5.         mGestureDetector = new GestureDetector((OnGestureListener) this);     
  6.         LinearLayout viewSnsLayout = (LinearLayout)findViewById(R.id.viewSnsLayout);     
  7.         viewSnsLayout.setOnTouchListener(this);     
  8.         viewSnsLayout.setLongClickable(true);     
  9.     }  

mGestureDetector为手势监听对象,下面的OnFling就是为其实现,用来处理手势的

viewSnsLayout.setOnTouchListener(this);表示viewSnsLayout这个layout的触屏事件由下面的OnTouch处理

 

3、重载onFling函数

Java代码 复制代码  收藏代码
  1. private int verticalMinDistance = 20;   
  2. private int minVelocity         = 0;   
  3.   
  4. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {   
  5.   
  6.     if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {   
  7.   
  8.         // 切换Activity   
  9.         // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);  
  10.         // startActivity(intent);   
  11.         Toast.makeText(this"向左手势", Toast.LENGTH_SHORT).show();   
  12.     } else if (e2.getX() - e1.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {   
  13.   
  14.         // 切换Activity   
  15.         // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);  
  16.         // startActivity(intent);   
  17.         Toast.makeText(this"向右手势", Toast.LENGTH_SHORT).show();   
  18.     }   
  19.   
  20.     return false;   
  21. }  

OnFling的四个参数意思分别为

Xml代码 复制代码  收藏代码
  1. e1  The first down motion event that started the fling.手势起点的移动事件   
  2. e2  The move motion event that triggered the current onFling.当前手势点的移动事件   
  3. velocityX   The velocity of this fling measured in pixels per second along the x axis.每秒x轴方向移动的像素   
  4. velocityY   The velocity of this fling measured in pixels per second along the y axis.每秒y轴方向移动的像素  

说的更简单点就是,鼠标手势相当于一个向量(当然有可能手势是曲线),e1为向量的起点,e2为向量的终点,velocityX为向量水平方向的速度,velocityY为向量垂直方向的速度

Java代码 复制代码  收藏代码
  1. if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity)  

 则上面的语句能知道啥意思了吧,就是说向量的水平长度必须大于verticalMinDistance,并且水平方向速度大于minVelocity

 

从而我们可以如此判断手势是否满足一定的条件从而进行相应响应,也可以根据这个写出更复杂的手势判断。

 

4、重载onTouch函数

在2中我们定义了viewSnsLayout的touch事件处理,下面我们来实现,直接调用手势的处理函数

Java代码 复制代码  收藏代码
  1. public boolean onTouch(View v, MotionEvent event) {   
  2.     return mGestureDetector.onTouchEvent(event);   
  3. }  

查看GestureDetector类的onTouchEvent的源码就能知道,进入该函数后会进入case MotionEvent.ACTION_UP这个路径,从而调用onFling函数

 

如果需要设置activity切换效果,在startActivity(intent);之后添加

overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);即可,可修改相应参数,可参考http://www.iteye.com/topic/1116472

 

其他:

关于activity添加ScrollView后onFling不起作用,无法滑动问题见http://trinea.iteye.com/blog/1213815



GestureDetector类

  1. public class GestureDetector {  
  2.   
  3.     // TODO: ViewConfiguration  
  4.     private int mBiggerTouchSlopSquare = 20 * 20;//touch事件最大超时时间的平方  
  5.   
  6.     private int mTouchSlopSquare;//touch事件超时的时间平方  
  7.     private int mDoubleTapSlopSquare;//双击事件超时时间的平方  
  8.     private int mMinimumFlingVelocity;//最小滑动速率  
  9.     private int mMaximumFlingVelocity;//最大滑动速率  
  10.   
  11.     private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();//长按超时  
  12.     private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();//单击超时  
  13.     private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();//双击超时  
  14.   
  15.     // constants for Message.what used by GestureHandler below  
  16.     private static final int SHOW_PRESS = 1;//短按标志  
  17.     private static final int LONG_PRESS = 2;//长按标志  
  18.     private static final int TAP = 3;//轻击标志  
  19.   
  20.     private final Handler mHandler;// Handler  
  21.     private final OnGestureListener mListener;// 普通手势监听器  
  22.     private OnDoubleTapListener mDoubleTapListener;// 双击或快速单击监听器  
  23.   
  24.     private boolean mStillDown;//是否按下就不动了  
  25.     private boolean mInLongPress;//是否在长按过程中   
  26.     private boolean mAlwaysInTapRegion;//是否一直点击同一个位置  
  27.     private boolean mAlwaysInBiggerTapRegion;//是否在更大的范围内点击  
  28.   
  29.     private MotionEvent mCurrentDownEvent;// 这次手势按下的事件  
  30.     private MotionEvent mPreviousUpEvent;// 上次手势抬起的事件  
  31.   
  32.       
  33.     //如果用户仍然处于第二次点击的过程(按下,滑动,抬起),就为true。只能为真 如果有双击事件的监听器就只能为true      
  34.     private boolean mIsDoubleTapping;  
  35.   
  36.     private float mLastMotionY;//最后一次动作的Y坐标  
  37.     private float mLastMotionX;//最后一次动作的X坐标  
  38.   
  39.     private boolean mIsLongpressEnabled;//长按事件是否启用  
  40.   
  41.     /** 
  42.      * 如果我们试用的API的版本级别>=Froyo,或者开发人员去显示的设置它,就为true。 
  43.      * 如果为true,输入事件>1个触摸点,将会被忽略。 
  44.      * 那么我们就能更好并排着的检测多点触控手势。 
  45.      */  
  46.     private boolean mIgnoreMultitouch;//是否支持多点touch事件  
  47.   
  48.     /** 
  49.      * 解决滑动持续时候的速度 
  50.      */  
  51.     private VelocityTracker mVelocityTracker;// 追踪触摸事件的速率  
  52.   
  53.     /** 
  54.      *处理某些指定的手势 
  55.      */  
  56.     private class GestureHandler extends Handler {  
  57.         GestureHandler() {  
  58.             super();  
  59.         }  
  60.   
  61.         GestureHandler(Handler handler) {  
  62.             super(handler.getLooper());  
  63.         }  
  64.   
  65.         @Override  
  66.         public void handleMessage(Message msg) {  
  67.             switch (msg.what) {  
  68.             case SHOW_PRESS:  
  69.                 mListener.onShowPress(mCurrentDownEvent);  
  70.                 break;  
  71.   
  72.             case LONG_PRESS:  
  73.                 dispatchLongPress();  
  74.                 break;  
  75.   
  76.             case TAP:  
  77.                 // If the user's finger is still down, do not count it as a tap  
  78.                 if (mDoubleTapListener != null && !mStillDown) {  
  79.                     mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);  
  80.                 }  
  81.                 break;  
  82.   
  83.             default:  
  84.                 throw new RuntimeException("Unknown message " + msg); // never  
  85.             }  
  86.         }  
  87.     }  
  88.   
  89.     /** 
  90.      * 在一个非UI线程中创建一个GestureDetector 
  91.      * 已经过时了,用下面的构造方法代替 
  92.      * public GestureDetector(Context context, OnGestureListener listener, Handler handler) 
  93.      */  
  94.     @Deprecated  
  95.     public GestureDetector(OnGestureListener listener, Handler handler) {  
  96.         this(null, listener, handler);  
  97.     }  
  98.       
  99.       
  100.     /** 
  101.      * 在一个非UI线程中创建一个GestureDetector 
  102.      * 已经过时了,用下面的构造方法代替 
  103.      * public GestureDetector(Context context, OnGestureListener listener, Handler handler) 
  104.      */  
  105.     @Deprecated  
  106.     public GestureDetector(OnGestureListener listener) {  
  107.         this(null, listener, null);  
  108.     }  
  109.   
  110.     /** 
  111.      * 在UI线程中创建一个GestureDetector 
  112.      */  
  113.     public GestureDetector(Context context, OnGestureListener listener) {  
  114.         this(context, listener, null);  
  115.     }  
  116.   
  117.     /** 
  118.      * 在UI线程中创建一个GestureDetector 
  119.      */  
  120.     public GestureDetector(Context context, OnGestureListener listener, Handler handler) {  
  121.         this(context, listener, handler, context != null  
  122.                 && context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.FROYO);  
  123.     }  
  124.   
  125.     /** 
  126.      * 在UI线程中创建一个GestureDetector 
  127.      * 不管你用的是哪个方法产生实例,都会调用这个构造器 
  128.      */  
  129.     public GestureDetector(Context context, OnGestureListener listener, Handler handler,  
  130.             boolean ignoreMultitouch) {  
  131.         if (handler != null) {  
  132.             mHandler = new GestureHandler(handler);  
  133.         } else {  
  134.             mHandler = new GestureHandler();  
  135.         }  
  136.         mListener = listener;  
  137.         //如果,这个listener只是实现了OnDoubleTapListener接口,就调用setOnDoubleTapListener方法  
  138.         //,初始化mDoubleTapListener对象  
  139.         if (listener instanceof OnDoubleTapListener) {  
  140.             setOnDoubleTapListener((OnDoubleTapListener) listener);  
  141.         }  
  142.         init(context, ignoreMultitouch);  
  143.     }  
  144.   
  145.     /** 
  146.      * 初始化信息 
  147.      */  
  148.     private void init(Context context, boolean ignoreMultitouch) {  
  149.         //如果没有手势检测类,将抛出异常  
  150.         if (mListener == null) {  
  151.             throw new NullPointerException("OnGestureListener must not be null");  
  152.         }  
  153.         mIsLongpressEnabled = true;//默认长按事件开启  
  154.         mIgnoreMultitouch = ignoreMultitouch;//对多点触摸的处理  
  155.   
  156.         // Fallback to support pre-donuts releases  
  157.         int touchSlop, doubleTapSlop;//touch超时,双击超时  
  158.         //对于一些超时操作需要变量的定义,通俗点说,就是不同事件的转变时间的问题  
  159.         //比如  按住多长,变为longPress事件,双击事件之间的时间间隔  
  160.         if (context == null) {  
  161.             // noinspection deprecation  
  162.             touchSlop = ViewConfiguration.getTouchSlop();  
  163.             doubleTapSlop = ViewConfiguration.getDoubleTapSlop();  
  164.             // noinspection deprecation  
  165.             mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity();  
  166.             mMaximumFlingVelocity = ViewConfiguration.getMaximumFlingVelocity();  
  167.         } else {  
  168.             final ViewConfiguration configuration = ViewConfiguration.get(context);  
  169.             touchSlop = configuration.getScaledTouchSlop();  
  170.             doubleTapSlop = configuration.getScaledDoubleTapSlop();  
  171.             mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();  
  172.             mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity();  
  173.         }  
  174.         mTouchSlopSquare = touchSlop * touchSlop;  
  175.         mDoubleTapSlopSquare = doubleTapSlop * doubleTapSlop;  
  176.     }  
  177.   
  178.     /** 
  179.      * 设置回调双击事件和解释手势行为的监听器 
  180.      */  
  181.     public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) {  
  182.         mDoubleTapListener = onDoubleTapListener;  
  183.     }  
  184.   
  185.     /** 
  186.      * 如果你设置true的话就是开启了长按键,当你长时间触屏不动就能得到 onLongPress 手势, 
  187.      * 如果设置false 那么你长时间触屏不移动也得不到这个手势的支持 
  188.      * 默认设置为true 
  189.      */  
  190.     public void setIsLongpressEnabled(boolean isLongpressEnabled) {  
  191.         mIsLongpressEnabled = isLongpressEnabled;  
  192.     }  
  193.   
  194.     /** 
  195.      * 返回长按事件传播的true或者false 
  196.      */  
  197.     public boolean isLongpressEnabled() {  
  198.         return mIsLongpressEnabled;  
  199.     }  
  200.   
  201.     /** 
  202.      * 分析给出的事件,如何适用的话,就会去触发我们所提供的OnGestureListener中的 
  203.      * 回调方法 
  204.      */  
  205.     public boolean onTouchEvent(MotionEvent ev) {  
  206.         final int action = ev.getAction();//事件的类型  
  207.         final float y = ev.getY();//事件的x坐标  
  208.         final float x = ev.getX();//事件的y坐标  
  209.   
  210.         //初始化速率追踪者,并将事件添加进去  
  211.         if (mVelocityTracker == null) {  
  212.             mVelocityTracker = VelocityTracker.obtain();  
  213.         }  
  214.         mVelocityTracker.addMovement(ev);  
  215.   
  216.         boolean handled = false;//是否要发消失  
  217.   
  218.         switch (action & MotionEvent.ACTION_MASK) {//判断事件的类型  
  219.         case MotionEvent.ACTION_POINTER_DOWN://非主触点按下的时候  
  220.             if (mIgnoreMultitouch) {//如果忽略多点触摸,那么就调用cancel()方法  
  221.                 // Multitouch event - abort.  
  222.                 cancel();  
  223.             }  
  224.             break;  
  225.   
  226.         case MotionEvent.ACTION_POINTER_UP://非主触点抬起的时候  
  227.             // Ending a multitouch gesture and going back to 1 finger  
  228.             if (mIgnoreMultitouch && ev.getPointerCount() == 2) {  
  229.                 //获得触点的id  
  230.                 int index = (((action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1  
  231.                         : 0;  
  232.                 mLastMotionX = ev.getX(index);//得到x,作为上一次的事件x坐标保存  
  233.                 mLastMotionY = ev.getY(index);//得到y,作为上一次的事件y坐标保存  
  234.                 mVelocityTracker.recycle();//回收mVelocityTracker  
  235.                 mVelocityTracker = VelocityTracker.obtain();//重现得到  
  236.             }  
  237.             break;  
  238.   
  239.         case MotionEvent.ACTION_DOWN://按下的事件  
  240.             if (mDoubleTapListener != null) {  
  241.                 boolean hadTapMessage = mHandler.hasMessages(TAP);  
  242.                 if (hadTapMessage)  
  243.                     mHandler.removeMessages(TAP);  
  244.                 if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage  
  245.                         && isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {  
  246.                     // This is a second tap  
  247.                     mIsDoubleTapping = true;  
  248.                     // Give a callback with the first tap of the double-tap  
  249.                     handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);  
  250.                     // Give a callback with down event of the double-tap  
  251.                     handled |= mDoubleTapListener.onDoubleTapEvent(ev);  
  252.                 } else {  
  253.                     // This is a first tap  
  254.                     mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);  
  255.                 }  
  256.             }  
  257.   
  258.             mLastMotionX = x;  
  259.             mLastMotionY = y;  
  260.             if (mCurrentDownEvent != null) {  
  261.                 mCurrentDownEvent.recycle();  
  262.             }  
  263.             mCurrentDownEvent = MotionEvent.obtain(ev);  
  264.             mAlwaysInTapRegion = true;  
  265.             mAlwaysInBiggerTapRegion = true;  
  266.             mStillDown = true;  
  267.             mInLongPress = false;  
  268.   
  269.             if (mIsLongpressEnabled) {  
  270.                 mHandler.removeMessages(LONG_PRESS);  
  271.                 mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()  
  272.                         + TAP_TIMEOUT + LONGPRESS_TIMEOUT);  
  273.             }  
  274.             mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime()  
  275.                     + TAP_TIMEOUT);  
  276.             handled |= mListener.onDown(ev);  
  277.             break;  
  278.   
  279.         case MotionEvent.ACTION_MOVE:  
  280.             if (mInLongPress || (mIgnoreMultitouch && ev.getPointerCount() > 1)) {  
  281.                 break;  
  282.             }  
  283.             final float scrollX = mLastMotionX - x;  
  284.             final float scrollY = mLastMotionY - y;  
  285.             if (mIsDoubleTapping) {  
  286.                 // Give the move events of the double-tap  
  287.                 handled |= mDoubleTapListener.onDoubleTapEvent(ev);  
  288.             } else if (mAlwaysInTapRegion) {  
  289.                 final int deltaX = (int) (x - mCurrentDownEvent.getX());  
  290.                 final int deltaY = (int) (y - mCurrentDownEvent.getY());  
  291.                 int distance = (deltaX * deltaX) + (deltaY * deltaY);  
  292.                 if (distance > mTouchSlopSquare) {  
  293.                     handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);  
  294.                     mLastMotionX = x;  
  295.                     mLastMotionY = y;  
  296.                     mAlwaysInTapRegion = fal6se;  
  297.                     mHandler.removeMessages(TAP);  
  298.                     mHandler.removeMessages(SHOW_PRESS);  
  299.                     mHandler.removeMessages(LONG_PRESS);  
  300.                 }  
  301.                 if (distance > mBiggerTouchSlopSquare) {  
  302.                     mAlwaysInBiggerTapRegion = false;  
  303.                 }  
  304.             } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {  
  305.                 handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);  
  306.                 mLastMotionX = x;  
  307.                 mLastMotionY = y;  
  308.             }  
  309.             break;  
  310.   
  311.         case MotionEvent.ACTION_UP:  
  312.             mStillDown = false;  
  313.             MotionEvent currentUpEvent = MotionEvent.obtain(ev);  
  314.             if (mIsDoubleTapping) {  
  315.                 // Finally, give the up event of the double-tap  
  316.                 handled |= mDoubleTapListener.onDoubleTapEvent(ev);  
  317.             } else if (mInLongPress) {  
  318.                 mHandler.removeMessages(TAP);  
  319.                 mInLongPress = false;  
  320.             } else if (mAlwaysInTapRegion) {  
  321.                 handled = mListener.onSingleTapUp(ev);  
  322.             } else {  
  323.   
  324.                 // A fling must travel the minimum tap distance  
  325.                 final VelocityTracker velocityTracker = mVelocityTracker;  
  326.                 velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);  
  327.                 final float velocityY = velocityTracker.getYVelocity();  
  328.                 final float velocityX = velocityTracker.getXVelocity();  
  329.   
  330.                 if ((Math.abs(velocityY) > mMinimumFlingVelocity)  
  331.                         || (Math.abs(velocityX) > mMinimumFlingVelocity)) {  
  332.                     handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);  
  333.                 }  
  334.             }  
  335.             if (mPreviousUpEvent != null) {  
  336.                 mPreviousUpEvent.recycle();  
  337.             }  
  338.             // Hold the event we obtained above - listeners may have changed the  
  339.             // original.  
  340.             mPreviousUpEvent = currentUpEvent;  
  341.             mVelocityTracker.recycle();  
  342.             mVelocityTracker = null;  
  343.             mIsDoubleTapping = false;  
  344.             mHandler.removeMessages(SHOW_PRESS);  
  345.             mHandler.removeMessages(LONG_PRESS);  
  346.             break;  
  347.         case MotionEvent.ACTION_CANCEL:  
  348.             cancel();  
  349.         }  
  350.         return handled;  
  351.     }  
  352.   
  353.     /** 
  354.      * 私有方法,取消的方法,移动消息队列中的消息,释放内存 
  355.      */  
  356.     private void cancel() {  
  357.         mHandler.removeMessages(SHOW_PRESS);  
  358.         mHandler.removeMessages(LONG_PRESS);  
  359.         mHandler.removeMessages(TAP);  
  360.         mVelocityTracker.recycle();  
  361.         mVelocityTracker = null;  
  362.         mIsDoubleTapping = false;  
  363.         mStillDown = false;  
  364.         if (mInLongPress) {  
  365.             mInLongPress = false;  
  366.         }  
  367.     }  
  368.   
  369.       
  370.     /** 
  371.      * 判断双击事件中,两次点击的位置关系。 
  372.      * 如果间隔很远,就不触发双击的事件 
  373.      */  
  374.     private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp,  
  375.             MotionEvent secondDown) {  
  376.         if (!mAlwaysInBiggerTapRegion) {  
  377.             return false;  
  378.         }  
  379.   
  380.         if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) {  
  381.             return false;  
  382.         }  
  383.   
  384.         int deltaX = (int) firstDown.getX() - (int) secondDown.getX();  
  385.         int deltaY = (int) firstDown.getY() - (int) secondDown.getY();  
  386.         return (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare);  
  387.     }  
  388.   
  389.     private void dispatchLongPress() {  
  390.         mHandler.removeMessages(TAP);  
  391.         mInLongPress = true;  
  392.         mListener.onLongPress(mCurrentDownEvent);  
  393.     }  


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ViewPager是一个Android中的View容器,可以让用户在多个页面之间进行滑动切换。要实现多页面滑动切换以及动画效果,可以按照以下步骤: 1. 在XML布局文件中添加ViewPager控件,并添加对应的布局文件,例如: ``` <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在Java代码中为ViewPager设置Adapter,用于显示多个页面。例如: ``` ViewPager viewPager = findViewById(R.id.viewPager); MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); ``` 其中,MyPagerAdapter是自定义的PagerAdapter类,需要继承自FragmentPagerAdapter或FragmentStatePagerAdapter。 3. 在自定义的PagerAdapter类中实现getItem()方法,用于返回每个页面的Fragment实例。例如: ``` @Override public Fragment getItem(int position) { switch (position) { case 0: return new Fragment1(); case 1: return new Fragment2(); case 2: return new Fragment3(); default: return null; } } ``` 其中,Fragment1、Fragment2、Fragment3是自定义的Fragment类,用于显示对应页面的内容。 4. 如果需要添加页面切换的动画效果,可以在Java代码中为ViewPager设置PageTransformer。例如: ``` viewPager.setPageTransformer(true, new DepthPageTransformer()); ``` 其中,DepthPageTransformer是自定义的PageTransformer类,用于实现页面切换时的动画效果。可以参考以下代码示例: ``` public class DepthPageTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE = 0.75f; public void transformPage(View view, float position) { int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0f); } else if (position <= 0) { // [-1,0] // Use the default slide transition when moving to the left page view.setAlpha(1f); view.setTranslationX(0f); view.setScaleX(1f); view.setScaleY(1f); } else if (position <= 1) { // (0,1] // Fade the page out. view.setAlpha(1 - position); // Counteract the default slide transition view.setTranslationX(pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0f); } } } ``` 以上就是实现Android中ViewPager多页面滑动切换以及动画效果的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值