前言
android事件处理,最复杂的就是对Touch事件的处理,因为Touch事件包括:down, move, up, cancle和多点触摸等多种情况,多点触摸的情况先不讨论,因为Touch有这么多的状态,所以Touch相对来说是最难处理的,下面就来讨论一下android是如何处理Touch事件的
事件主要方法
//分发
//super.dispatchTouchEvent(ev) --> 将事件向上传递 --> 交给父容器 处理是否分发
//true --> 不向下分发 --> 不向上传递 --> 我自己来处理所有事件
//false --> 不向下分发 --> 向上传递 --> 完成父容器的事件
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.e("GAO", "CustomView-dispatchTouchEvent");
return false;
}
//拦截
//return true 进行拦截 --> 不向下给子控件传递事件
//return false 不进行拦截
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e("GAO", "CustomView-onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
}
//所有触摸事件
//按下
//移动
//抬起
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("GAO", "CustomView-onTouchEvent");
return super.onTouchEvent(event);
}
进行事件拦截走向测试
<com.mine.touchdemo.CustomLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mine.touchdemo.CustomView
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mine.touchdemo.CustomTextView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.mine.touchdemo.CustomView>
</com.mine.touchdemo.CustomLayout>
默认事件打印
2020-01-07 16:02:38.312 24136-24136/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomView-onInterceptTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomTextView-onInterceptTouchEvent
2020-01-07 16:02:38.315 24136-24136/com.mine.touchdemo E/GAO: CustomTextView-onInterceptTouchEvent
2020-01-07 16:02:38.315 24136-24136/com.mine.touchdemo E/GAO: CustomView-onTouchEvent
2020-01-07 16:02:38.316 24136-24136/com.mine.touchdemo E/GAO: CustomLayout-onTouchEvent
dispatchTouchEvent return true
2020-01-07 16:16:18.484 24839-24839/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:16:18.484 24839-24839/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:16:18.484 24839-24839/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent
dispatchTouchEvent return false
2020-01-07 16:17:29.689 25066-25066/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:17:29.689 25066-25066/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:17:29.690 25066-25066/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent
2020-01-07 16:17:29.691 25066-25066/com.mine.touchdemo E/GAO: CustomLayout-onTouchEvent
onInterceptTouchEvent return true
2020-01-07 16:18:57.270 25291-25291/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:18:57.271 25291-25291/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:18:57.271 25291-25291/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent
2020-01-07 16:18:57.271 25291-25291/com.mine.touchdemo E/GAO: CustomView-onInterceptTouchEvent
2020-01-07 16:18:57.272 25291-25291/com.mine.touchdemo E/GAO: CustomView-onTouchEvent
2020-01-07 16:18:57.272 25291-25291/com.mine.touchdemo E/GAO: CustomLayout-onTouchEvent
Fragment 添加下拉刷新 Demo
public class FragmentRefreshLayout extends FrameLayout {
private LinearLayout mRefreshLayout;
private LinearLayout mMainLayout;
private int mMaxRefreshHeight = 200;
private PointF mBeforePointF;
public FragmentRefreshLayout(Context context) {
super(context);
initView();
initData();
}
public FragmentRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
initData();
}
private void initView() {
setBackgroundColor(Color.GRAY);
mMainLayout = new LinearLayout(getContext());
LayoutParams mainParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mMainLayout.setLayoutParams(mainParams);
mMainLayout.setBackgroundColor(Color.WHITE);
mRefreshLayout = new LinearLayout(getContext());
LayoutParams refreshParams = new LayoutParams(LayoutParams.MATCH_PARENT, mMaxRefreshHeight);
refreshParams.topMargin = -mMaxRefreshHeight;
mRefreshLayout.setLayoutParams(refreshParams);
mRefreshLayout.setBackgroundColor(Color.RED);
addView(mRefreshLayout);
addView(mMainLayout);
}
private void initData() {
mBeforePointF = new PointF();
}
//分发事件
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mBeforePointF.x = ev.getX();
mBeforePointF.y = ev.getY();
} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
//偏移量
float xDimension = Math.abs(ev.getX() - mBeforePointF.x);
float yDimension = Math.abs(ev.getY() - mBeforePointF.y);
//判读滑动方向
if (xDimension > yDimension * 1.5) {
//X轴滑动
return super.dispatchTouchEvent(ev);
}
//最小响应距离
if (yDimension < 5) {
return super.dispatchTouchEvent(ev);
}
//可滑动范围
//Main下拉
LayoutParams mainParams = (LayoutParams) mMainLayout.getLayoutParams();
if (mainParams.topMargin < 0) {
mainParams.topMargin = 0;
}
if (mainParams.topMargin > mMaxRefreshHeight) {
mainParams.topMargin = mMaxRefreshHeight;
}
mainParams.topMargin += ev.getY() - mBeforePointF.y;
mMainLayout.setLayoutParams(mainParams);
requestLayout();
mBeforePointF.x = ev.getX();
mBeforePointF.y = ev.getY();
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
//当滑动位置,打开或关闭
LayoutParams mainParams = (LayoutParams) mMainLayout.getLayoutParams();
if (mainParams.topMargin < 100) {
startAnim(mainParams.topMargin, 0);
} else {
startAnim(mainParams.topMargin, mMaxRefreshHeight);
}
}
return true;
}
private void startAnim(int start, int end) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(start, end);
valueAnimator.setDuration(500);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
LayoutParams mainParams = (LayoutParams) mMainLayout.getLayoutParams();
mainParams.topMargin = (int) animation.getAnimatedValue();
mMainLayout.setLayoutParams(mainParams);
requestLayout();
}
});
valueAnimator.start();
}
}