多层view触摸传递分析
来源:互联网 发布:鹊桥淘宝客是什么 编辑:程序博客网 时间:2024/05/18 03:24
android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。
一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP
当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。呵呵,为什么呢?看看下面我的调查结果你就明白了。
android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent
当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由 dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。
下面作者给出个例子,demo如下图显示:
demo分为3层,最外层scrollview,中间是listview,最里面是包裹了scrollview的textview。
源码中最外层的scrollview和listview都为自定义view,重载了dispatchKeyEvent(KeyEvent event) ,onInterceptTouchEvent(MotionEvent ev),并且都返回false,根据上图来看,就是说明都交给下层处理,scrollview先交给listview处理,listview不管,又交给list-item处理,所以最后一层的控件响应了滑动事件。
下面贴上源码以供后期参考方便:
布局文件:
main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.boredream.demo.tedispatch.MyScrollView android:id="@+id/sv_top" android:layout_width="fill_parent" android:layout_height="400dp" android:background="#fff" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <com.boredream.demo.tedispatch.MyListView android:id="@+id/lv_mid" android:layout_width="fill_parent" android:layout_height="600dp" android:layout_marginBottom="100dp" android:layout_marginLeft="50dp" android:layout_marginTop="100dp" android:background="#000" /> </LinearLayout> </com.boredream.demo.tedispatch.MyScrollView></LinearLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/tv_bottom" android:layout_width="wrap_content" android:layout_height="fill_parent" android:textColor="#fff" /> <ScrollView android:layout_width="fill_parent" android:layout_height="150dp" android:layout_marginLeft="50dp" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#060" android:text="bottom" android:textSize="200sp" /> </ScrollView></LinearLayout>
最外层自定义scrollview:
package com.boredream.demo.tedispatch;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.view.MotionEvent;import android.widget.ScrollView;public class MyScrollView extends ScrollView {public MyScrollView(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {return false;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {return false;}}
自定义listview:
package com.boredream.demo.tedispatch;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.view.MotionEvent;import android.widget.ListView;public class MyListView extends ListView {public MyListView(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {return false;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {return false;}}
MainActivity:
package com.boredream.demo.tedispatch;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;public class TouchEventDispatchDemoActivity extends Activity {private ListView lv_mid;private MyAdapter adapter;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);lv_mid = (ListView) findViewById(R.id.lv_mid);adapter = new MyAdapter();lv_mid.setAdapter(adapter);}private class MyAdapter extends BaseAdapter {@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = View.inflate(TouchEventDispatchDemoActivity.this, R.layout.listview_item, null);TextView tv_bottom = (TextView) view.findViewById(R.id.tv_bottom);tv_bottom.setText("bottom item textview " + (position + 1));return view;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic int getCount() {return 20;}};}
- 多层view触摸传递分析
- Android View 触摸事件传递
- Android View 触摸事件传递机制
- Android View触摸事件传递机制
- Android View触摸事件传递机制
- Android View触摸事件传递机制 一
- android view触摸事件传递机制测试
- View事件传递分析
- android触摸event传递源码分析二
- Android探索------触摸事件传递机制分析
- Android的触摸事件传递分析
- Android触摸事件传递机制简要分析
- Android View之间的触摸事件传递图
- Android——View的触摸传递机制
- 【Android View】Android中View对触摸事件的处理和传递dispatchTouchEvent、onInterceptTouchEvent
- Android O: 触摸事件传递流程源码分析(上)
- Android O: 触摸事件传递流程源码分析(下)
- Android触摸事件源码分析:Activity->ViewGroup->View
- 信息: validateJarFile(D:\tomcat\Tomcat 5.5\webapps\CH_9\WEB-INF\lib\javax.servlet.jar) - jar not loade
- codeforces 305 C. Ivan and Powers of Two
- Android 对话框(Dialog)大全 建立你自己的对话框
- Oracle外部表详解
- 理解group by(小示例)
- 多层view触摸传递分析
- 设置Samba服务器中新建文件/目录的权限
- org.apache.jasper.JasperException: java.lang.NullPointerException
- php 中require() include() require_once()
- gvim 备份文件去除 配置
- jQuery设置光标停留位置在文本最后(或在具体的位置)的办法
- Could not create the Java virtual machine 解决
- 关于JQ选中元素
- log4j配置说明