Android事件分发机制案例分析(一)
来源:互联网 发布:网络销售食品药品 编辑:程序博客网 时间:2024/06/07 05:53
最近在做东西的时候发现自己对事件的分发(传递)机制理解的并不清楚,可以说是错误的理解了事件分发机制。对此,自己找了一些实例的例子,来加深对Android的时间分发机制的理解。废话不多说,直入主题。
下图是这个案例的实现界面:
对于上面实现的xml代码很简单,下图注明其容器和控件的结构:
如果上面的示意图表达的不清楚,请看以下代码:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.test.youkumenu.MainActivity"> <RelativeLayout android:id="@+id/rl_level1" android:layout_width="100dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level1"> <ImageButton android:id="@+id/ib_home" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@null" android:src="@drawable/icon_home" /> </RelativeLayout> <RelativeLayout android:id="@+id/rl_level2" android:layout_width="180dp" android:layout_height="90dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level2"> <ImageButton android:id="@+id/ib_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="5dp" android:background="@null" android:src="@drawable/icon_menu" /> <ImageButton android:id="@+id/search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:background="@android:color/transparent" android:src="@drawable/icon_search" /> <ImageButton android:id="@+id/question" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="5dp" android:background="@android:color/transparent" android:src="@drawable/icon_myyouku" /> </RelativeLayout> <RelativeLayout android:id="@+id/rl_level3" android:layout_width="280dp" android:layout_height="140dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level3"> <ImageButton android:id="@+id/house" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="5dp" android:background="@null" android:src="@drawable/channel4" /> <ImageButton android:id="@+id/music" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentStart="true" android:layout_marginBottom="11dp" android:layout_marginStart="14dp" android:background="@null" android:src="@drawable/channel1" /> <ImageButton android:id="@+id/microphone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignTop="@+id/music" android:layout_marginEnd="12dp" android:background="@null" android:src="@drawable/channel7" /> <ImageButton android:id="@+id/media" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/tv_show" android:layout_toEndOf="@+id/music" android:background="@null" android:src="@drawable/channel2" /> <ImageButton android:id="@+id/tv_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/microphone" android:layout_marginBottom="14dp" android:layout_toStartOf="@+id/microphone" android:background="@null" android:src="@drawable/channel5" /> <ImageButton android:id="@+id/editing" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/monkey" android:layout_marginEnd="15dp" android:layout_toStartOf="@+id/tv_show" android:background="@null" android:src="@drawable/channel6" /> <ImageButton android:id="@+id/monkey" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/house" android:layout_marginStart="11dp" android:layout_toEndOf="@+id/media" android:background="@null" android:src="@drawable/channel3" /> </RelativeLayout></RelativeLayout>
上面的布局结构是为了实现优酷菜单的动画效果,但是本次不是针对动画,所以就不做实现的说明了。
对上图而言,结构上level2部分覆盖了level1,level3部分覆盖了level2,对于level3而言没有谁覆盖它,所以它的事件传递序列很简单,
即:根布局容器RelativeLayout—>level3的RelativeLayout容器—>level3上上面的原子View(不能拆分的控件,最基本结构的控件)
那么,如果要设置level2和level1容器(RelativeLayout)
的子控件的点击事件,怎么办呢?
直接添加View.OnClickListener接口,使用setOnClickListener设置监听?
运行结果就不截图了,每次的点击事件都直接被level3容器视图消费了,只有level3的OnClick事件打印出了log,为什么呢?那就要分析下Android事件分发机制的原理了。借助本次的实例,做以下分析,如图:
相信看了上面这张图,应该很容易理解为什么点击事件会被level3拦截,而不继续向下层传递了,对于每一个level,其内部的事件传递跟上面一样,只是原子控件没有onInterceptTouchEvent方法,因为他是最基本的控件,所以上面让level1,level2响应level3传递下来的事件就很容易解决了.
想让level2及其控件响应事件,就让level3的onTouch返回false,不消费事件,让其向level2传递,一次类推,让level1及其控件响应事件,则然level2的onTouch返回false,不消费事件即可,下面看实际代码。
private void initView() { //事件拦截处理 //rl_level3需要把事件传递给rl_level2和rl_level1 rl_level1 = (RelativeLayout) findViewById(R.id.rl_level1); rl_level1.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); /* rl_level1.onInterceptTouchEvent(MotionEvent ev); 拦截TouchEvent rl_level1.dispatchTouchEvent(); 分发TouchEvent rl_level1.onTouchEvent() 触摸事件 */ rl_level2 = (RelativeLayout) findViewById(R.id.rl_level2); rl_level2.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); rl_level3 = (RelativeLayout) findViewById(R.id.rl_level3); //让上层的RelativeLayout不消费 rl_level3.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); ib_home = (ImageButton) findViewById(R.id.ib_home); ib_home.setOnClickListener(this); ib_menu = (ImageButton) findViewById(R.id.ib_menu); ib_menu.setOnClickListener(this); findViewById(R.id.search).setOnClickListener(this);//搜索 findViewById(R.id.question).setOnClickListener(this);//问题 findViewById(R.id.media).setOnClickListener(this);//多媒体 findViewById(R.id.editing).setOnClickListener(this);//剪辑 findViewById(R.id.house).setOnClickListener(this);// findViewById(R.id.microphone).setOnClickListener(this); findViewById(R.id.music).setOnClickListener(this); findViewById(R.id.monkey).setOnClickListener(this); findViewById(R.id.tv_show).setOnClickListener(this); }
运行结果:
可以看出,所有的图标按钮都响应了对应的事件。
- Android事件分发机制案例分析(一)
- Android事件分发机制分析
- android事件分发机制分析
- Android 事件分发机制分析
- Android事件分发机制(一)
- android 事件分发机制一
- android事件分发机制一
- Android事件分发机制一
- Android事件分发分析(一)
- android之View和ViewGroup事件分发机制分析(一)(View的事件分发机制)
- 分析Android的Touch事件分发机制
- Android事件分发机制源码分析
- Android事件分发机制源码分析
- Android事件分发机制源码分析
- Android 事件拦截和分发机制分析
- Android事件分发机制源码分析
- 源码分析android的事件分发机制
- Android事件分发机制代码片段分析
- Java Static Variables
- 哈夫曼编码
- linux c之网络编程之TCP(服务器和和客户端基础通信)
- javaBean 的三个标签
- 1.Android日志工具的使用(Log)
- Android事件分发机制案例分析(一)
- Install Java in Linux(Ubuntu/Debian)
- TCP的三次握手和四次挥手
- 用scikit-learn研究局部线性嵌入(LLE)
- 【Github】Github客户端安装方法
- C语言itoa()函数和atoi()函数详解
- 错误票据
- 仿QQ、微信翻页查看聊天记录
- 输入20个整数,输出其中能被数组中其它元素整除的那些数组元素