Android的事件分发实例分析
如果對(duì)Android的事件分發(fā)不熟悉,可以看Android的事件分發(fā)
瀑布流
實(shí)現(xiàn)的功能:滑動(dòng)左邊的RecyclerView區(qū)域,左邊的RecyclerView滾動(dòng);滑動(dòng)中間的RecyclerView上半部分區(qū)域,三個(gè)RecyclerView一起滾動(dòng)(聯(lián)動(dòng)),滑動(dòng)中間的RecyclerView下半部分區(qū)域,中間的RecyclerView滾動(dòng);滑動(dòng)右邊的RecyclerView區(qū)域,右邊的RecyclerView滾動(dòng)
布局文件
<?xml version="1.0" encoding="utf-8"?> <com.github.waterfall.view.CustomLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:paddingLeft="2dp"android:paddingRight="2dp"><android.support.v7.widget.RecyclerView android:id="@+id/rv1"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><android.support.v7.widget.RecyclerView android:id="@+id/rv2"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><android.support.v7.widget.RecyclerView android:id="@+id/rv3"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/></com.github.waterfall.view.CustomLinearLayout>自定義CustomLinearLayout,實(shí)現(xiàn)touch事件分發(fā)
package com.github.waterfall.view;import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout;/*** ============================================================* Copyright:${TODO}有限公司版權(quán)所有 (c) 2017* Author: AllenIverson* Email: 815712739@qq.com* GitHub: https://github.com/JackChen1999* 博客: http://blog.csdn.net/axi295309066* 微博: AndroidDeveloper* <p>* Project_Name:WaterFall* Package_Name:com.github.waterfall.view* Version:1.0* time:2016/3/3 11:06* des :${TODO}* gitVersion:2.12.0.windows.1* updateAuthor:$Author$* updateDate:$Date$* updateDes:${TODO}* ============================================================*/ public class CustomLinearLayout extends LinearLayout {public CustomLinearLayout(Context context) {super(context);}public CustomLinearLayout(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {return true;}@Overridepublic boolean onTouchEvent(MotionEvent event) {int childCount = getChildCount();int width = getWidth() / childCount;int height = getHeight();float downX = event.getX();if (downX < width) {//滑動(dòng)左邊的RecyclerViewevent.setLocation(width / 2, event.getY());getChildAt(0).dispatchTouchEvent(event);return true;} else if (downX > width && downX < width * 2) {//滑動(dòng)中間的RecyclerViewfloat downY = event.getY();if (downY < height / 2) {event.setLocation(width / 2, event.getY());for (int i = 0; i < childCount; i++) {View child = getChildAt(i);try {child.dispatchTouchEvent(event);} catch (Exception e) {e.printStackTrace();}}return true;} else if (downY > height / 2) {event.setLocation(width / 2, event.getY());try {getChildAt(1).dispatchTouchEvent(event);} catch (Exception e) {e.printStackTrace();}return true;}} else if (downX > width * 2) {//滑動(dòng)右邊的RecyclerViewevent.setLocation(width / 2, event.getY());getChildAt(2).dispatchTouchEvent(event);return true;}return true;} }重寫onInterceptTouchEvent()方法,并返回true,攔截touch事件,在onTouchEvent()方法中,判斷touch事件的區(qū)域,如果滑動(dòng)的是左邊的RecyclerView區(qū)域,調(diào)用getChildAt(0).dispatchTouchEvent(event)將touch事件分發(fā)給左邊的RecyclerView;如果滑動(dòng)的是右邊的RecyclerView區(qū)域,將touch事件分發(fā)給右邊的RecyclerView;如果滑動(dòng)的是中間的RecyclerView上半部分區(qū)域,將touch事件分發(fā)給三個(gè)RecyclerView,從而實(shí)現(xiàn)三個(gè)RecyclerView的聯(lián)動(dòng),如果滑動(dòng)的是中間的RecyclerView下半部分區(qū)域,則將touch事件分發(fā)給中間的RecyclerView
InterceptorFrame
package com.mwqi.ui.widget;import android.content.Context; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.FrameLayout; import com.mwqi.ui.activity.BaseActivity; import com.mwqi.utils.UIUtils; import com.mwqi.utils.ViewUtils;import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map;public class InterceptorFrame extends FrameLayout {public static final int ORIENTATION_UP = 0x1;public static final int ORIENTATION_DOWN = 0x2;public static final int ORIENTATION_LEFT = 0x4;public static final int ORIENTATION_RIGHT = 0x8;public static final int ORIENTATION_ALL = 0x10;private List<View> mInterceptorViews;private Map<View, Integer> mViewAndOrientation;private int mTouchSlop;private float mLastX;private float mLastY;private View mTarget;public InterceptorFrame(Context context) {super(context);init();}private void init() {mInterceptorViews = new LinkedList<View>();mViewAndOrientation = new HashMap<View, Integer>();final ViewConfiguration configuration = ViewConfiguration.get(getContext());mTouchSlop = configuration.getScaledTouchSlop();}public void addInterceptorView(final View v, final int orientation) {UIUtils.runInMainThread(new Runnable() {@Overridepublic void run() {if (!mInterceptorViews.contains(v)) {mInterceptorViews.add(v);mViewAndOrientation.put(v, orientation);}}});}public void removeInterceptorView(final View v) {UIUtils.runInMainThread(new Runnable() {@Overridepublic void run() {mInterceptorViews.remove(v);mViewAndOrientation.remove(v);}});}private View isTouchInterceptedView(MotionEvent event, int orientation) {for (View v : mInterceptorViews) {if (ViewUtils.isTouchInView(event, v) && (mViewAndOrientation.get(v) & orientation) == orientation && v.dispatchTouchEvent(event)) {return v;}}return null;}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {int action = ev.getAction();if (mTarget != null) {boolean flag = mTarget.dispatchTouchEvent(ev);if (flag && (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP)) {mTarget = null;}return flag;}final float x = ev.getX();final float y = ev.getY();View view = null;switch (action) {case MotionEvent.ACTION_DOWN:mLastX = x;mLastY = y;view = isTouchInterceptedView(ev, ORIENTATION_ALL);break;case MotionEvent.ACTION_MOVE:final int xDiff = (int) Math.abs(x - mLastX);final int yDiff = (int) Math.abs(y - mLastY);if (xDiff > mTouchSlop && xDiff > yDiff) {view = isTouchInterceptedView(ev, (x - mLastX > 0) ? ORIENTATION_RIGHT : ORIENTATION_LEFT);} else if (yDiff > mTouchSlop && yDiff > xDiff) {view = isTouchInterceptedView(ev, (y - mLastY > 0) ? ORIENTATION_DOWN : ORIENTATION_UP);}break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:mTarget = null;break;default:break;}if (view != null) {mTarget = view;return true;} else {return super.dispatchTouchEvent(ev);}} }代碼:http://download.csdn.net/detail/axi295309066/9769415
總結(jié)
以上是生活随笔為你收集整理的Android的事件分发实例分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android应用程序模块:应用、任务、
- 下一篇: Android java.lang.Un