Touch事件--对GestureDetector的理解

作用

简单来说,GestureDetector对View触摸事件的封装。它是触摸事件的帮助类。

我们知道通过重新复写View/ViewGroup的dispatchTouchEvent方法,可以定义View对触摸事件的处理。但是,如果我们根据这些事件完成对一个View的双击、滑动(fling)等触摸操作,还是比较困难的。因为我们要写很多关于算法类的东西。而使用GestureDetector,就会省事很多,我们可以只处理我们关心的事件。例如:doubleClick,press等。而不用识别用户的TouchEvent。

用法

1. 构造GestureDetector。GestureDetector构造函数一定要传OnGestureListener传监听器,他包装了down、press、longPress、sigleTapUp、scroll、fling等事件。另外我们也可以在GestureDetector设置 setOnDoubleTapListener对双击事件的监听,通过setContextClickListener设置对单击事件的监听。推荐使用GestureDetector.SimpleOnGestureListener适配器实现。可减少代码的编写。

注意:当我们对一些手势关心时(需要处理的手势),要在返回值设为true.

2. 将事件交给GestureDetector处理。我们可以通过自定义View,或者给View设置onTouchListener实现。是通过将event事件传递给gestureDet.onTouchEvent(event);实现的。

        view.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                gestureDet.onTouchEvent(event);
                return true;
            }
        });

完整代码

package com.tiandh.tdhtest01;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

import com.tiandh.tdhtest01.view.MoveRelativeLayout;

/**
 * Created by Administrator on 2017/5/15 0015.
 */

public class TestScroller extends AppCompatActivity implements View.OnClickListener {

    private Button buttonSelf;
    private LinearLayout llScroller;

    private MoveRelativeLayout viewParent;
    private View moveView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_scroller);
        buttonSelf = (Button) findViewById(R.id.bt_scroll_self);
        llScroller = (LinearLayout) findViewById(R.id.ll_scroller);
        findViewById(R.id.bt_scroll_self).setOnClickListener(this);
        findViewById(R.id.bt_scroll_parent).setOnClickListener(this);
        initGestureTest();
    }

    private GestureDetector.OnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {

        @Override
        public boolean onDown(MotionEvent e) {
            Log.i("tag", "onDown--");
            return true;
        }

        @Override
        public void onShowPress(MotionEvent e) {
            Log.i("tag", "onPress--");
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            Log.i("tag", "e1.getX=" + e1.getX() + ", e1.getY=" + e1.getY() + ", e2.getX=" + e2.getX() + ", e2.getY=" + e2.getY());
            viewParent.scrollTo((int) -e2.getX(), (int) -e2.getY());
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            Log.i("tag", "onLongPress--");
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            Log.i("tag", "onFling e1.getX=" + e1.getX() + ", e2.getX=" + e2.getX() + ", vx=" + velocityX + ", vy=" + velocityY);
            viewParent.fling((int) -e2.getX(), (int) -e2.getY(), (int) -velocityX, (int) -velocityY);
            return true;
        }
    };

    private void initGestureTest() {
        viewParent = (MoveRelativeLayout) findViewById(R.id.rl_content);
        final GestureDetector gestureDet = new GestureDetector(this, gestureListener);
        viewParent.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gestureDet.onTouchEvent(event);
            }
        });
        moveView = findViewById(R.id.view_move);
    }

    int i;

    @Override
    public void onClick(View v) {
        //注意view的scrollTo,scrollBy是view里面内容滑动
        switch (v.getId()) {
            case R.id.bt_scroll_self:
                if (i++ % 2 == 1) {
                    buttonSelf.scrollTo(60, 0);
                } else {
                    buttonSelf.scrollTo(0, 0);
                }
                break;
            case R.id.bt_scroll_parent:
                if (i++ % 2 == 1) {
                    llScroller.scrollTo(60, 0);
                } else {
                    llScroller.scrollTo(0, 0);
                }
                break;
        }
    }
}

MoveRelativeLayout.java

package com.tiandh.tdhtest01.view;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.RelativeLayout;
import android.widget.Scroller;

/**
 * Created by Administrator on 2017/5/15 0015.
 */

public class MoveRelativeLayout extends RelativeLayout {

    private Scroller scroller;
    private Handler mHander;

    public MoveRelativeLayout(Context context) {
        this(context, null);
    }

    public MoveRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MoveRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        scroller = new Scroller(context);
        mHander = new Handler();
    }

    public void fling( int startX, int startY, int velocityX, int velocityY  ) {
        scroller.fling(startX, startY, velocityX, velocityY, -getWidth(), getWidth(), -getHeight(), getHeight());
        startFling();
    }

    private void startFling() {
        Log.i("tag", "srcoller X="+getScrollX());
        if(scroller.computeScrollOffset()){
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            mHander.postDelayed(new Runnable() {
                @Override
                public void run() {
                    startFling();
                }
            }, 50);
        }
    }
}

activity_test_scroller.xml




    



你可能感兴趣的:(Android笔记)