Android的事件分发实例分析
来源:互联网 发布:python爬取百度文库 编辑:程序博客网 时间:2024/05/21 11:03
如果对Android的事件分发不熟悉,可以看Android的事件分发
瀑布流
实现的功能:滑动左边的RecyclerView区域,左边的RecyclerView滚动;滑动中间的RecyclerView上半部分区域,三个RecyclerView一起滚动(联动),滑动中间的RecyclerView下半部分区域,中间的RecyclerView滚动;滑动右边的RecyclerView区域,右边的RecyclerView滚动
布局文件
<?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,实现touch事件分发
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}有限公司版权所有 (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); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return true; } @Override public boolean onTouchEvent(MotionEvent event) { int childCount = getChildCount(); int width = getWidth() / childCount; int height = getHeight(); float downX = event.getX(); if (downX < width) {//滑动左边的RecyclerView event.setLocation(width / 2, event.getY()); getChildAt(0).dispatchTouchEvent(event); return true; } else if (downX > width && downX < width * 2) {//滑动中间的RecyclerView float 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) {//滑动右边的RecyclerView event.setLocation(width / 2, event.getY()); getChildAt(2).dispatchTouchEvent(event); return true; } return true; }}
重写onInterceptTouchEvent()方法,并返回true,拦截touch事件,在onTouchEvent()方法中,判断touch事件的区域,如果滑动的是左边的RecyclerView区域,调用getChildAt(0).dispatchTouchEvent(event)将touch事件分发给左边的RecyclerView;如果滑动的是右边的RecyclerView区域,将touch事件分发给右边的RecyclerView;如果滑动的是中间的RecyclerView上半部分区域,将touch事件分发给三个RecyclerView,从而实现三个RecyclerView的联动,如果滑动的是中间的RecyclerView下半部分区域,则将touch事件分发给中间的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() { @Override public void run() { if (!mInterceptorViews.contains(v)) { mInterceptorViews.add(v); mViewAndOrientation.put(v, orientation); } } }); } public void removeInterceptorView(final View v) { UIUtils.runInMainThread(new Runnable() { @Override public 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; } @Override public 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
0 0
- Android的事件分发实例分析
- 分析Android的Touch事件分发机制
- android 的事件分发从源码分析
- 源码分析android的事件分发机制
- Android的事件分发源码分析,告别事件冲突。
- Android事件分发分析(一)
- Android事件分发深入分析
- Android事件分发源码分析
- Android事件分发机制分析
- android事件分发机制分析
- Android事件分发源码分析
- Android 事件分发机制分析
- Android事件分发源码分析
- Android事件的分发
- android事件的分发
- Android的事件分发
- Android事件的分发
- Android的事件分发
- angular-cli的安装及各种坑
- 关于微信发送中文 总是显示\u***”
- VB 共享软件防破解设计技术初探(二)
- Ubuntu下安装matlab2016b
- js调用百度分享功能能
- Android的事件分发实例分析
- NGUI 3.x 深度管理及渲染优化
- pom文件解析
- linux内核版本与大页内存
- Android-自定义图像资源的使用(2)
- 高精度加法==
- java创建银行账户,自定义取钱超过余额异常
- Button点击事件和LIstview子控件点击事件失效
- eclipse maven 项目 出现红色叹号 解决方法