简单来说,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);
}
}
}