Android(安卓)View事件分发机制理解
16lz
2021-01-26
MainActiviity
public class MainActivity extends Activity { private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); init(); } private void init() { tv.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("-----------DOWN-------"); break; case MotionEvent.ACTION_UP: System.out.println("-----------UP-------"); break; default: break; } //return false; return true; } }); }}
main.xml
<com.example.testevent.MyLinearLayout 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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.testevent.MainActivity" > <com.example.testevent.MyTextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" />com.example.testevent.MyLinearLayout>
其中MyLinearLayout继承LinearLayout
public class MyLinearLayout extends LinearLayout{ @SuppressLint("NewApi") public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public MyLinearLayout(Context context) { super(context); // TODO Auto-generated constructor stub } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: System.out.println("MyLinearLayout ---ACTION_DOWN ---"); break; case MotionEvent.ACTION_UP: System.out.println("MyLinearLayout ---ACTION_UP ---"); break; default: break; } System.out.println("MyLinearLayout ---onTouchEvent ---"); return true; //return super.onTouchEvent(event); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub System.out.println("MyLinearLayout ---onInterceptTouchEvent ---"); return super.onInterceptTouchEvent(ev); //return true; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub System.out.println("MyLinearLayout ---dispatchTouchEvent ---"); return super.dispatchTouchEvent(ev); //return true; }}
MyTextView继承TextView
public class MyTextView extends TextView { public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public MyTextView(Context context) { super(context); // TODO Auto-generated constructor stub } public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub } @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: System.out.println("MyTextView ---ACTION_DOWN ---"); break; case MotionEvent.ACTION_UP: System.out.println("MyTextView ---ACTION_UP ---"); break; default: break; } System.out.println("MyTextView ---onTouchEvent ---"); return super.onTouchEvent(event); // return true; } @Override public boolean dispatchTouchEvent(MotionEvent event) { // TODO Auto-generated method stub System.out.println("MyTextView ---dispatchTouchEvent ---"); return super.dispatchTouchEvent(event); //return true; }}
先看第一张图
通过图我们可以看到事件分发默认情况是由父控件捕捉向子控件传递,子控件不消费(但可以做自己的其他逻辑),最后再回传到父控件,父控件进行消费。
当子控件消费(onTouchEvent返回true)后,不再回传给父控件。这有点类似java的继承关系。如果父控件拦截(onInterceptTouchEvent返回true)之后,将不会传递给子控件。
再看第二张
通过图我们可以看到setOnTouchListener的优先级高于onTouchEvent。
最后,为了方便大家理解,我贴一下整理的输出内容,大家看图不明白,可以对着输出内容来理解
默认:10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---dispatchTouchEvent ---10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:07:55.076: I/System.out(2502): MyTextView ---dispatchTouchEvent ---10-05 04:07:55.076: I/System.out(2502): MyTextView ---ACTION_DOWN ---10-05 04:07:55.076: I/System.out(2502): MyTextView ---onTouchEvent ---10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---ACTION_DOWN ---10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---onTouchEvent ---MyTextView-- onTouchEvent----return true===10-05 04:14:15.616: I/System.out(2548): MyLinearLayout ---dispatchTouchEvent ---10-05 04:14:15.616: I/System.out(2548): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:14:15.616: I/System.out(2548): MyTextView ---dispatchTouchEvent ---10-05 04:14:15.616: I/System.out(2548): MyTextView ---ACTION_DOWN ---10-05 04:14:15.616: I/System.out(2548): MyTextView ---onTouchEvent ---10-05 04:14:15.696: I/System.out(2548): MyLinearLayout ---dispatchTouchEvent ---10-05 04:14:15.696: I/System.out(2548): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:14:15.696: I/System.out(2548): MyTextView ---dispatchTouchEvent ---10-05 04:14:15.696: I/System.out(2548): MyTextView ---ACTION_UP ---10-05 04:14:15.696: I/System.out(2548): MyTextView ---onTouchEvent ---MyTextView-- dispatchTouchEvent----return true=== //onTouchEvent&&dispatchTouchEvent----return true===10-05 04:16:39.676: I/System.out(2591): MyLinearLayout ---dispatchTouchEvent ---10-05 04:16:39.676: I/System.out(2591): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:16:39.676: I/System.out(2591): MyTextView ---dispatchTouchEvent ---10-05 04:16:39.746: I/System.out(2591): MyLinearLayout ---dispatchTouchEvent ---10-05 04:16:39.746: I/System.out(2591): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:16:39.746: I/System.out(2591): MyTextView ---dispatchTouchEvent ---MyLinearLayout-- onTouchEvent----return true=== 10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---dispatchTouchEvent ---10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:22:09.476: I/System.out(2677): MyTextView ---dispatchTouchEvent ---10-05 04:22:09.476: I/System.out(2677): MyTextView ---ACTION_DOWN ---10-05 04:22:09.476: I/System.out(2677): MyTextView ---onTouchEvent ---10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---ACTION_DOWN ---10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---onTouchEvent ---10-05 04:22:09.546: I/System.out(2677): MyLinearLayout ---dispatchTouchEvent ---10-05 04:22:09.546: I/System.out(2677): MyLinearLayout ---ACTION_UP ---10-05 04:22:09.546: I/System.out(2677): MyLinearLayout ---onTouchEvent ---MyLinearLayout-- onInterceptTouchEvent----return true10-05 04:28:40.086: I/System.out(2720): MyLinearLayout ---dispatchTouchEvent ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---ACTION_DOWN ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onTouchEvent ---MyLinearLayout-- dispatchTouchEvent----return true===10-05 04:31:52.536: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---10-05 04:31:52.636: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ----------------------------------------------------------setOnTouchListener--- return false=======默认:10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---dispatchTouchEvent ---10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:48:19.746: I/System.out(3243): MyTextView ---dispatchTouchEvent ---10-05 04:48:19.746: I/System.out(3243): -----------DOWN-------10-05 04:48:19.746: I/System.out(3243): MyTextView ---ACTION_DOWN ---10-05 04:48:19.746: I/System.out(3243): MyTextView ---onTouchEvent ---10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---ACTION_DOWN ---10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---onTouchEvent ---MyTextView--dispatchTouchEvent----return true10-05 05:00:27.706: I/System.out(3419): MyLinearLayout ---dispatchTouchEvent ---10-05 05:00:27.706: I/System.out(3419): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:00:27.706: I/System.out(3419): MyTextView ---dispatchTouchEvent ---10-05 05:00:27.786: I/System.out(3419): MyLinearLayout ---dispatchTouchEvent ---10-05 05:00:27.786: I/System.out(3419): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:00:27.786: I/System.out(3419): MyTextView ---dispatchTouchEvent ---MyTextView--onTouchEvent----return true10-05 05:03:39.846: I/System.out(3462): MyLinearLayout ---dispatchTouchEvent ---10-05 05:03:39.846: I/System.out(3462): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:03:39.846: I/System.out(3462): MyTextView ---dispatchTouchEvent ---10-05 05:03:39.846: I/System.out(3462): -----------DOWN-------10-05 05:03:39.846: I/System.out(3462): MyTextView ---ACTION_DOWN ---10-05 05:03:39.846: I/System.out(3462): MyTextView ---onTouchEvent ---10-05 05:03:39.926: I/System.out(3462): MyLinearLayout ---dispatchTouchEvent ---10-05 05:03:39.936: I/System.out(3462): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:03:39.936: I/System.out(3462): MyTextView ---dispatchTouchEvent ---10-05 05:03:39.936: I/System.out(3462): -----------UP-------10-05 05:03:39.936: I/System.out(3462): MyTextView ---ACTION_UP ---10-05 05:03:39.936: I/System.out(3462): MyTextView ---onTouchEvent ---MyLinearLayout-- dispatchTouchEvent----return true===== MyTextView-- setOnTouchListener无效10-05 04:31:52.536: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---10-05 04:31:52.636: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---MyLinearLayout-- onInterceptTouchEvent----return true===== MyTextView-- setOnTouchListener无效10-05 04:28:40.086: I/System.out(2720): MyLinearLayout ---dispatchTouchEvent ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---ACTION_DOWN ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onTouchEvent ---MyLinearLayout-- onTouchEvent----return true===== 10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---dispatchTouchEvent ---10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:51:30.926: I/System.out(3374): MyTextView ---dispatchTouchEvent ---10-05 04:51:30.926: I/System.out(3374): -----------DOWN-------10-05 04:51:30.926: I/System.out(3374): MyTextView ---ACTION_DOWN ---10-05 04:51:30.926: I/System.out(3374): MyTextView ---onTouchEvent ---10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---ACTION_DOWN ---10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---onTouchEvent ---10-05 04:51:31.006: I/System.out(3374): MyLinearLayout ---dispatchTouchEvent ---10-05 04:51:31.006: I/System.out(3374): MyLinearLayout ---ACTION_UP ---10-05 04:51:31.006: I/System.out(3374): MyLinearLayout ---onTouchEvent ----------------------------------------------------------setOnTouchListener--- return true=======默认:10-05 05:07:06.376: I/System.out(3506): MyLinearLayout ---dispatchTouchEvent ---10-05 05:07:06.376: I/System.out(3506): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:07:06.376: I/System.out(3506): MyTextView ---dispatchTouchEvent ---10-05 05:07:06.376: I/System.out(3506): -----------DOWN-------10-05 05:07:06.466: I/System.out(3506): MyLinearLayout ---dispatchTouchEvent ---10-05 05:07:06.466: I/System.out(3506): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:07:06.466: I/System.out(3506): MyTextView ---dispatchTouchEvent ---10-05 05:07:06.466: I/System.out(3506): -----------UP-------MyTextView--dispatchTouchEvent----return true10-05 05:08:28.256: I/System.out(3549): MyLinearLayout ---dispatchTouchEvent ---10-05 05:08:28.256: I/System.out(3549): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:08:28.256: I/System.out(3549): MyTextView ---dispatchTouchEvent ---10-05 05:08:28.356: I/System.out(3549): MyLinearLayout ---dispatchTouchEvent ---10-05 05:08:28.356: I/System.out(3549): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:08:28.356: I/System.out(3549): MyTextView ---dispatchTouchEvent ---MyTextView--onTouchEvent----return true10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:09:57.316: I/System.out(3592): MyTextView ---dispatchTouchEvent ---10-05 05:09:57.316: I/System.out(3592): -----------DOWN-------10-05 05:09:57.396: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---10-05 05:09:57.406: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:09:57.406: I/System.out(3592): MyTextView ---dispatchTouchEvent ---10-05 05:09:57.426: I/System.out(3592): -----------UP-------MyLinearLayout-- dispatchTouchEvent----return true==== MyTextView-- setOnTouchListener无效10-05 04:31:52.536: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---10-05 04:31:52.636: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---MyLinearLayout-- onInterceptTouchEvent----return true===== MyTextView-- setOnTouchListener无效10-05 04:28:40.086: I/System.out(2720): MyLinearLayout ---dispatchTouchEvent ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onInterceptTouchEvent ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---ACTION_DOWN ---10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onTouchEvent ---MyLinearLayout-- onTouchEvent----return true10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:09:57.316: I/System.out(3592): MyTextView ---dispatchTouchEvent ---10-05 05:09:57.316: I/System.out(3592): -----------DOWN-------10-05 05:09:57.396: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---10-05 05:09:57.406: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---10-05 05:09:57.406: I/System.out(3592): MyTextView ---dispatchTouchEvent ---10-05 05:09:57.426: I/System.out(3592): -----------UP-------
更多相关文章
- Android实现控件动画效果
- Android(安卓)日期控件选择
- Android(安卓)查看大图(直接复制可以用)
- android 下拉刷新控件
- Android(安卓)animated-rotate简单的图片旋转动画
- Android(安卓)控件GridView的使用
- Android(安卓)Studio默认产生Fragment
- android自定义适配屏幕的ImageView
- Android常用控件之RecyclerView