300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Android View事件传递机制

Android View事件传递机制

时间:2019-09-26 10:54:44

相关推荐

Android View事件传递机制

view事件传递机制,在很多面试中会问道,我曾经也被问道,却没有回答上来。

写这篇博客前参考了/zuguorui/article/details/76862816。在这里感谢该作者,写的很详细。

今天我在这里写了一个demo去理解这个view的事件传递机制。

首先这个view包括两种,viewGroup和普通view。viewGroup就是里面还可以包含子控件的那种,如LinearLayout,ViewPager;view是指不能包含子view的那种,如Button,TextView,ImageView 等。

viewGroup的view传递事件按顺序是:

dispatchTouchEvent(分发)onInterceptTouchEvent(拦截)onTouchEvent(触摸)

view的事件传递顺序是

dispatchTouchEvent(分发)onTouchEvent(触摸)

两者结合的一般顺序是

如果子控件没有消费掉触摸事件

viewPager: dispatchTouchEventviewPager: onInterceptTouchEventmyImageView: dispatchTouchEventmyImageView: onTouchEventviewPager: onTouchEvent

如果子控件消费掉触摸事件,比如执行了onClick方法,执行完onClick后,就不会再执行父控件的onTouchEvent

viewPager: dispatchTouchEventviewPager: onInterceptTouchEventmyImageView: dispatchTouchEventmyImageView: onTouchEventmyImageView: onclick

如果onInterceptTouchEvent 返回true,则父控件消费触摸事件

如果onInterceptTouchEvent 返回false,则子控件消费触摸事件

我们来写demo看看,这个机制到底是怎么实现的。我使用viewPage和image做的测试。

我自己测试发现一个有趣的事情,

1、onInterceptTouchEvent 不做任何修改,

return super.onInterceptTouchEvent(ev)

a 子view的onTouchEvent 不做任何修改

return super.onTouchEvent(event);

如果子view不消费onTouchEvent 事件,则一次滑动中,父控件不会多次调用onInterceptTouchEvent

09-13 16:55:21.427 6089-6089/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:55:21.428 6089-6089/.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent09-13 16:55:21.429 6089-6089/.vieweventapplication E/view_event_myImageView: dispatchTouchEvent09-13 16:55:21.429 6089-6089/.vieweventapplication E/view_event_myImageView: onTouchEvent09-13 16:55:21.429 6089-6089/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:55:21.438 6089-6089/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:55:21.438 6089-6089/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:55:21.452 6089-6089/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:55:21.452 6089-6089/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:55:21.460 6089-6089/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:55:21.460 6089-6089/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:55:21.468 6089-6089/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:55:21.468 6089-6089/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:55:21.476 6089-6089/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:55:21.477 6089-6089/.vieweventapplication E/view_event_viewPager: onTouchEvent

b 如果子控件onTouchEvent 返回true,view group 则会多次调用onInterceptTouchEvent。

09-13 17:12:47.652 7371-7371/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 17:12:47.652 7371-7371/.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent09-13 17:12:47.652 7371-7371/.vieweventapplication E/view_event_myImageView: dispatchTouchEvent09-13 17:12:47.652 7371-7371/.vieweventapplication E/view_event_myImageView: onTouchEvent09-13 17:12:47.727 7371-7371/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 17:12:47.727 7371-7371/.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent09-13 17:12:47.727 7371-7371/.vieweventapplication E/view_event_myImageView: dispatchTouchEvent09-13 17:12:47.727 7371-7371/.vieweventapplication E/view_event_myImageView: onTouchEvent09-13 17:12:47.738 7371-7371/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 17:12:47.738 7371-7371/.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent09-13 17:12:47.738 7371-7371/.vieweventapplication E/view_event_myImageView: dispatchTouchEvent09-13 17:12:47.738 7371-7371/.vieweventapplication E/view_event_myImageView: onTouchEvent09-13 17:12:47.760 7371-7371/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 17:12:47.760 7371-7371/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 17:12:47.776 7371-7371/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 17:12:47.776 7371-7371/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 17:12:47.777 7371-7371/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 17:12:47.777 7371-7371/.vieweventapplication E/view_event_viewPager: onTouchEvent

2、onInterceptTouchEvent 返回true

输出如下,不会调用子view的方法

09-13 16:52:34.841 4478-4478/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:52:34.841 4478-4478/.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent09-13 16:52:34.842 4478-4478/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:52:34.848 4478-4478/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:52:34.848 4478-4478/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:52:34.864 4478-4478/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:52:34.864 4478-4478/.vieweventapplication E/view_event_viewPager: onTouchEvent09-13 16:52:34.871 4478-4478/.vieweventapplication E/view_event_viewPager: dispatchTouchEvent09-13 16:52:34.871 4478-4478/.vieweventapplication E/view_event_viewPager: onTouchEvent

3、onInterceptTouchEvent 返回false,子view的onTouchevent

return super.onTouchEvent(event);

这个时候,viewPager 可以滑动

3、onInterceptTouchEvent 返回false,子view的onTouchevent

return true;

这个时候,viewPager 就不能滑动了

测试源码如下,复写的viewPager

package .vieweventapplication;import android.content.Context;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.view.MotionEvent;/*** Created by dfgx_yinlijuan on /9/13.10:06*/public class MyViewPager extends ViewPager {String tag="viewPager";public MyViewPager(@NonNull Context context) {super(context);}public MyViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {Tools.log(tag,"dispatchTouchEvent");return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent ev) {Tools.log(tag,"onTouchEvent");return super.onTouchEvent(ev);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {Tools.log(tag,"onInterceptTouchEvent");return super.onInterceptTouchEvent(ev);// return false;}}

复写的ImageView

package .vieweventapplication;import android.content.Context;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.ImageView;/*** Created by dfgx_yinlijuan on /9/13.14:49*/public class MyImageView extends android.support.v7.widget.AppCompatImageView {String tag="myImageView";public MyImageView(Context context) {super(context);}public MyImageView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public MyImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {Tools.log(tag,"dispatchTouchEvent");return super.dispatchTouchEvent(event);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Tools.log(tag,"onTouchEvent");return super.onTouchEvent(event);// return true;}}

activity 调用

package .vieweventapplication;import android.graphics.Color;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;/*** view 事件传递机制demo*/public class ViewEventActivty extends AppCompatActivity {final String tag = "button";ViewPager viewPager;List<View> views=new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.actvity_view_event);MyViewPager viewPager = (MyViewPager) findViewById(R.id.viewPager);// viewPager.setAdapter(new GuidePageAdapter());for (int i = 0; i < 3; i++) {MyImageView imageView = new MyImageView(this);if (i == 0) {imageView.setBackgroundColor(Color.RED);} else if (i == 1) {imageView.setBackgroundColor(Color.GREEN);} else if (i == 2) {imageView.setBackgroundColor(Color.BLUE);}imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));views.add(imageView);}GuideAdapter adapter = new GuideAdapter(views);viewPager.setAdapter(adapter);}class GuideAdapter extends PagerAdapter {List<View> mViews;GuideAdapter(List<View> views) {this.mViews = views;}@Overridepublic int getCount() {return mViews.size();}@Overridepublic boolean isViewFromObject(@NonNull View view, @NonNull Object object) {return view==object;}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {((ViewPager) container).removeView(mViews.get(position));}@Overridepublic Object instantiateItem(@NonNull ViewGroup container, int position) {((ViewPager)container).addView(mViews.get(position));return mViews.get(position);}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。