Android上下与左右滑动事件处理
需要源码的同学评论留邮箱。
package com.jp.touch;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
/**
* 拦截左右滑动的相对布局<br>
*
* 注意viewgroup的target view 认定功能,一当找到目标view后续事件就直接传递给它了<br>
*
* 所以我们这里不需要去根据用户手势设定是上下还是左右滑动的模式<br>
*
* @author qianjp
*
*/
public class TouchRelativeLayout extends RelativeLayout {
private static final String tag = "TouchRelativeLayout";
private static final String dispatchTag = " dispatchTouchEvent ";
private static final String onInterTag = " onInterceptTouchEvent ";
private static final String ontouchTag = " onTouchEvent ";
// 本类使用分析器
private GestureDetector mInterceptGestureDetector;
private GestureDetector mTouchEventGestureDetector;
// 手势分析结果回调
private OnGestureDetectorListener onGestureDetectorListener;
public TouchRelativeLayout(Context context) {
super(context);
init(context);
}
public TouchRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mInterceptGestureDetector = new GestureDetector(context,
new warpInterceptScrollDetector());
mTouchEventGestureDetector = new GestureDetector(context,
new warpTouchEventScrollDetector());
// fadingEdge属性用来设置拉滚动条时,边框渐变的放向。
// none(边框颜色不变),horizontal(水平方向颜色变淡),vertical(垂直方向颜色变淡)。
// fadingEdgeLength用来设置边框渐变的长度。
setFadingEdgeLength(0);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
switch (actionMasked) {
case MotionEvent.ACTION_DOWN:
Log.i(tag, this.getClass().getSimpleName() + dispatchTag
+ "ACTION_DOWN");
break;
case MotionEvent.ACTION_CANCEL:
Log.i(tag, this.getClass().getSimpleName() + dispatchTag
+ "ACTION_CANCEL");
break;
case MotionEvent.ACTION_MASK:
Log.i(tag, this.getClass().getSimpleName() + dispatchTag
+ "ACTION_MASK");
break;
case MotionEvent.ACTION_SCROLL:
Log.i(tag, this.getClass().getSimpleName() + dispatchTag
+ "ACTION_SCROLL");
break;
case MotionEvent.ACTION_MOVE:
Log.i(tag, this.getClass().getSimpleName() + dispatchTag
+ "ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.i(tag, this.getClass().getSimpleName() + dispatchTag
+ "ACTION_UP");
break;
}
boolean returnFlg = super.dispatchTouchEvent(ev);
Log.i(tag, "------" + this.getClass().getSimpleName()
+ " dispatchTouchEvent return " + returnFlg);
return returnFlg;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
* 1.一般down事件不拦截,只要target view 是它的子view,它就能一直收到事件,事件是一层层传递的<br>
*
* 2.move 事件一当拦截后续所有事件都不再走此方法,会直接传给本ViewGroup的onTouchEvent方法<br>
*/
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
switch (actionMasked) {
case MotionEvent.ACTION_DOWN:
Log.i(tag, this.getClass().getSimpleName() + onInterTag
+ "ACTION_DOWN");
break;
case MotionEvent.ACTION_CANCEL:
Log.i(tag, this.getClass().getSimpleName() + onInterTag
+ "ACTION_CANCEL");
break;
case MotionEvent.ACTION_MASK:
Log.i(tag, this.getClass().getSimpleName() + onInterTag
+ "ACTION_MASK");
break;
case MotionEvent.ACTION_SCROLL:
Log.i(tag, this.getClass().getSimpleName() + onInterTag
+ "ACTION_SCROLL");
break;
case MotionEvent.ACTION_MOVE:
Log.i(tag, this.getClass().getSimpleName() + onInterTag
+ "ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.i(tag, this.getClass().getSimpleName() + onInterTag
+ "ACTION_UP");
break;
}
boolean returnFlg = mInterceptGestureDetector.onTouchEvent(ev);
Log.i(tag, "------" + this.getClass().getSimpleName()
+ " onInterceptTouchEvent return " + returnFlg);
return returnFlg;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
switch (actionMasked) {
case MotionEvent.ACTION_DOWN:
Log.i(tag, this.getClass().getSimpleName() + ontouchTag
+ "ACTION_DOWN");
break;
case MotionEvent.ACTION_CANCEL:
Log.i(tag, this.getClass().getSimpleName() + ontouchTag
+ "ACTION_CANCEL");
break;
case MotionEvent.ACTION_MASK:
Log.i(tag, this.getClass().getSimpleName() + ontouchTag
+ "ACTION_MASK");
break;
case MotionEvent.ACTION_SCROLL:
Log.i(tag, this.getClass().getSimpleName() + ontouchTag
+ "ACTION_SCROLL");
break;
case MotionEvent.ACTION_MOVE:
Log.i(tag, this.getClass().getSimpleName() + ontouchTag
+ "ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.i(tag, this.getClass().getSimpleName() + ontouchTag
+ "ACTION_UP");
// break;
// up 事件直接回调,因手势分析器对up事件分析经常丢失
return onGestureDetectorListener.onUp(event);
}
// 将事件给touch分析器分析后再给使用者
boolean returnFlg = mTouchEventGestureDetector.onTouchEvent(event);
Log.i(tag, "------" + this.getClass().getSimpleName()
+ " onTouchEvent return " + returnFlg);
return returnFlg;
}
/*
* 用以分析onInterceptTouchEvent方法的事件<br>
*
* *down事件一般不拦截所以不分析,move事件拦截一次后后续事件不走onInterceptTouchEvent所以up也不分析<br>
*/
class warpInterceptScrollDetector extends SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
if (Math.abs(distanceY) >= Math.abs(distanceX)) {
Log.e("jj", "上下....");
return false;
}
Log.e("jj", "左右....");
return true;
}
}
/*
* 用以分析onTouchEvent方法的事件<br>
*/
class warpTouchEventScrollDetector extends SimpleOnGestureListener {
public boolean onSingleTapUp(MotionEvent e) {
// 轻触,不move,抬起
return false;
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// move事件
// 回调给使用者处理
return onGestureDetectorListener.onScroll(e1, e2, distanceX,
distanceY);
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// 快速滑动抬起
return false;
}
}
public void setOnGestureDetectorListener(
OnGestureDetectorListener onGestureDetectorListener) {
this.onGestureDetectorListener = onGestureDetectorListener;
}
/**
* 监听viewgroup拦截的手势,回调move和up事件<br>
*
* @author qianjp
*
*/
public interface OnGestureDetectorListener {
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY);
public boolean onUp(MotionEvent event);
}
}
更多相关文章
- Android中事件处理之LongClickListener实现步骤
- Android处理scrollciew里嵌套ExpandableListView的滑动事件
- android修改软键盘的回车键为搜索键以及点击时执行两次监听事件
- Android中EventBus事件总线发送网络请求结果更新UI
- android 事件总线 -- Otto(一)
- Android.GridView事件监听
- design principle:模拟 android Button 控件点击事件
- Android 设置DrawableRight和DrawableLeft点击事件
- Android开发(九)| android手势开发