前言
android事件處理,最復(fù)雜的就是對(duì)Touch事件的處理,因?yàn)門ouch事件包括:down, move, up, cancle和多點(diǎn)觸摸等多種情況,多點(diǎn)觸摸的情況先不討論,因?yàn)門ouch有這么多的狀態(tài),所以Touch相對(duì)來說是最難處理的,下面就來討論一下android是如何處理Touch事件的
事件主要方法
//分發(fā)
//super.dispatchTouchEvent(ev) --> 將事件向上傳遞 --> 交給父容器 處理是否分發(fā)
//true --> 不向下分發(fā) --> 不向上傳遞 --> 我自己來處理所有事件
//false --> 不向下分發(fā) --> 向上傳遞 --> 完成父容器的事件
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.e("GAO", "CustomView-dispatchTouchEvent");
return false;
}
//攔截
//return true 進(jìn)行攔截 --> 不向下給子控件傳遞事件
//return false 不進(jìn)行攔截
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e("GAO", "CustomView-onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
}
//所有觸摸事件
//按下
//移動(dòng)
//抬起
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("GAO", "CustomView-onTouchEvent");
return super.onTouchEvent(event);
}
進(jìn)行事件攔截走向測試
<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>
默認(rèn)事件打印
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();
}
//分發(fā)事件
@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);
//判讀滑動(dòng)方向
if (xDimension > yDimension * 1.5) {
//X軸滑動(dòng)
return super.dispatchTouchEvent(ev);
}
//最小響應(yīng)距離
if (yDimension < 5) {
return super.dispatchTouchEvent(ev);
}
//可滑動(dòng)范圍
//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) {
//當(dāng)滑動(dòng)位置,打開或關(guān)閉
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();
}
}