手機進入智能機時代,觸摸屏也已成爲主流之勢,原來的手機按鍵也被屏幕點觸取代,滑動屏幕操作則相對屏幕點擊更能獲得用戶的青睞,習慣了各種瀏覽器的鼠標手勢、pad等平板的切滑、類似iReader的軟件豐富的手勢後,是不是也想自己的軟件能夠用食指炫起來呢,下面就讓我們來看看android的手勢操作吧
先介紹下左右滑動切換Activity,對於複雜的手勢原理一樣,具體後述。
主要原理爲監控觸屏事件和手勢事件,在觸屏事件處理函數中調用手勢事件處理函數,表示用戶觸屏後是否有手勢操作,有則進行手勢事件處理,大致分爲四步
1、需要繼承OnGestureListener和OnDoubleTapListener,如下:
- public class ViewSnsActivity extends Activity implements OnTouchListener, OnGestureListener
這兩個類分別是觸屏監聽器和手勢監控器,具體可查看OnTouchListener和OnGestureListener
2、在添加mGestureDetector的定義,並在ViewSnsActivity的onCreate函數中加入其頁面佈局的setOnTouchListener事件
- GestureDetector mGestureDetector;
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.view_sns_activity);
- mGestureDetector = new GestureDetector((OnGestureListener) this);
- LinearLayout viewSnsLayout = (LinearLayout)findViewById(R.id.viewSnsLayout);
- viewSnsLayout.setOnTouchListener(this);
- viewSnsLayout.setLongClickable(true);
- }
mGestureDetector爲手勢監聽對象,下面的OnFling就是爲其實現,用來處理手勢的
viewSnsLayout.setOnTouchListener(this);表示viewSnsLayout這個layout的觸屏事件由下面的OnTouch處理
3、重載onFling函數
- private int verticalMinDistance = 20;
- private int minVelocity = 0;
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {
- // 切換Activity
- // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);
- // startActivity(intent);
- Toast.makeText(this, "向左手勢", Toast.LENGTH_SHORT).show();
- } else if (e2.getX() - e1.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {
- // 切換Activity
- // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);
- // startActivity(intent);
- Toast.makeText(this, "向右手勢", Toast.LENGTH_SHORT).show();
- }
- return false;
- }
OnFling的四個參數意思分別爲
- e1 The first down motion event that started the fling.手勢起點的移動事件
- e2 The move motion event that triggered the current onFling.當前手勢點的移動事件
- velocityX The velocity of this fling measured in pixels per second along the x axis.每秒x軸方向移動的像素
- velocityY The velocity of this fling measured in pixels per second along the y axis.每秒y軸方向移動的像素
說的更簡單點就是,鼠標手勢相當於一個向量(當然有可能手勢是曲線),e1爲向量的起點,e2爲向量的終點,velocityX爲向量水平方向的速度,velocityY爲向量垂直方向的速度
- if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity)
則上面的語句能知道啥意思了吧,就是說向量的水平長度必須大於verticalMinDistance,並且水平方向速度大於minVelocity
從而我們可以如此判斷手勢是否滿足一定的條件從而進行相應響應,也可以根據這個寫出更復雜的手勢判斷。
4、重載onTouch函數
在2中我們定義了viewSnsLayout的touch事件處理,下面我們來實現,直接調用手勢的處理函數
- public boolean onTouch(View v, MotionEvent event) {
- return mGestureDetector.onTouchEvent(event);
- }
查看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後或是外部爲RelativeLayout時onFling不起作用,無法滑動問題見http://trinea.iteye.com/blog/1213815