左右滑動跳轉頁面的優雅實現
左右滑動跳轉頁面好像不是很常見,不知道是習慣問題還是什麼原因。但是在使用一些App的時候,發現都有這個左右滑動,使用起來確實方便。不用去點選一些裡手指老遠的按鈕。可能是習慣的問題,就是想不起來去用它,奇怪。
大概長這個樣子,很清新很簡潔

slide.gif
一、直接但複雜的方式
直接重寫onTouchEvent方法,根據使用者的點選事件,不斷的獲取位置,進而判斷是否是滑動事件?左滑還是右滑?當然整個過程都是需要自己定義變數來儲存當前的和其他位置資料,以及一些計算操作。還是有些稍顯複雜的。
這裡就不介紹這種方式,why?因為我們追求的是優雅的實現。好吧,其實是因為懶[滑稽笑]。
二、優雅的實現
左滑右滑屬於手勢操作,那麼這裡有一個類專門用於檢測的手勢操作的。那就是GestureDetector。
GestureDetector(手勢檢測)
用於檢測使用者的單擊、滑動、長按、雙擊點事件
藉助這個類我們可以很容易的實現滑動效果。
1.準備了三個Activity
MainActivity和要滑動過去的兩個Activity。
我們主要操作的是MainActivity,其他兩個是什麼樣子都很隨意撒。
2.MainActivity
public class MainActivity extends AppCompatActivity{ GestureDetector mGestureDetector;//手勢檢測物件 private static final String TAG = "MainActivity"; privatestaticfinalintFLING_MIN_DISTANCE =50 ;//滑動最小的距離 privatestaticfinalintFLING_MIN_VELOCITY =0 ;//滑動最小的速度 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGestureDetector = newGestureDetector(this,new MyGestureListener()); } @Override public boolean onTouchEvent(MotionEvent event) { return mGestureDetector.onTouchEvent(event); } }
可以看到MainActivity裡的內容是很簡單的。
主要做了兩件事:
(1)在onCreate方法裡實例化物件
mGestureDetector = newGestureDetector(this,new MyGestureListener());
可以看到方法引數裡有例項化了一個MyGestureListener物件,MyGestureListener是幹什麼的呢?這個就是監測手勢是否滑動的實現,後面會詳細說這個。
(2)重寫onTouchEvent方法
點選事鍵的處理轉移到手勢檢測的事件中
@Override public boolean onTouchEvent(MotionEvent event) { return mGestureDetector.onTouchEvent(event); }
3.MyGestureListener
這裡就是實現監聽手勢操作的具體實現了
(1)首先讓它繼承GestureDetector裡的SimpleOnGestureListener類。
classMyGestureListener extendsGestureDetector.SimpleOnGestureListener{ }
這個SimpleOnGestureListener裡面有一些手勢操作的方法,比如單擊、長按等,其中onFiling是我們這裡要關注的點。我們的滑動檢測就需要重寫這個方法。先看看這個類的實現。
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,OnContextClickListener { public boolean onSingleTapUp(MotionEvent e) { return false; } public void onLongPress(MotionEvent e) { } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } public void onShowPress(MotionEvent e) { } public boolean onDown(MotionEvent e) { return false; } ....... }
(2)重點就是如何檢測滑動手勢了
我們需要重寫onFling方法,這個方法裡有四個引數,
前兩個引數表示你滑動開始和滑動結束時的事件物件,
後兩個引數表示你滑動開始和滑動結束時的速度物件
之後通過前兩個引數可以獲取滑動開始和結束時所在的位置並通過這個位置計算得到滑動距離,然後和你定義的最短滑動距離一比較來確定是否是一次滑動。
還可以通過後兩個引數獲取滑動的速度和你定義的最小滑動速度比較,判斷是否是一次成功的滑動。
當然也可以通過滑動前的位置和滑動後的位置之差來確定是向左還是向右滑動。完整程式碼如下:
classMyGestureListener extendsGestureDetector.SimpleOnGestureListener{ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e1.getX()-e2.getX()>FLING_MIN_DISTANCE&&Math.abs(velocityX)>FLING_MIN_VELOCITY){ Toast.makeText(MainActivity.this, "向左手勢", Toast.LENGTH_SHORT).show(); Intent leftIntent=new Intent(MainActivity.this,LeftActivity.class); startActivity(leftIntent); //滑動動畫 overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left); }else if(e2.getX()-e1.getX()>FLING_MIN_DISTANCE&&Math.abs(velocityX)>FLING_MIN_VELOCITY){ Toast.makeText(MainActivity.this, "向右手勢", Toast.LENGTH_SHORT).show(); Intent rightIntent=new Intent(MainActivity.this,RightActivity.class); startActivity(rightIntent); //滑動動畫 overridePendingTransition(R.anim.in_from_left, R.anim.out_to_right); } return false; } }
(3)在程式碼裡跳轉活動的時候我加個滑動動畫,讓滑動看起來更人性化。
動畫實現如下:
overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left);

anim.jpg
in_from_left.xml 從左邊進入
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" > <translate android:duration="1000" android:fromXDelta="-100%p" android:toXDelta="0%p" /> </set>
in_from_right.xml 從右邊進入
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:duration="1000" android:fromXDelta="100%p" android:toXDelta="0%p" /> </set>
out_to_left.xml 從左邊出去
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:duration="1000" android:fromXDelta="0%p" android:toXDelta="-100%p" /> </set>
out_ro_right 從右邊出去
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:duration="1000" android:fromXDelta="0%p" android:toXDelta="100%p" /> </set>
這樣我們就實現了通過左右滑動來跳轉Activity了,整個實現過程還是很優雅的。