本文为自己多年来在Android实战开发过程中总结归纳的一些常见问题,现在分享出来希望对初学者有所帮助。 

本文出自门心叼龙的博客,转载请注明出处: https://blog.csdn.net/geduo_83/article/details/86560896
<https://blog.csdn.net/geduo_83/article/details/86560896>    


事件分发是Android开发过程中的重点又是难点, 一张事件分发流程图,让你彻底搞明白。网上有很多文章写事件分发,感觉都没有讲明白,恭喜你,今天你看到好文章了,你彻底搞清楚...

目录

1.在Android操作系统中,拥有事件传递功能的类都有哪些?
<https://blog.csdn.net/geduo_83/article/details/86560896#main-toc>

2.触摸事件的类型?
<https://blog.csdn.net/geduo_83/article/details/86560896#2.%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9F>

3.事件传递的三个阶段?
<https://blog.csdn.net/geduo_83/article/details/86560896#3.%E4%BA%8B%E4%BB%B6%E4%BC%A0%E9%80%92%E7%9A%84%E4%B8%89%E4%B8%AA%E9%98%B6%E6%AE%B5%EF%BC%9F>

4.简述View的事件传递机制?
<https://blog.csdn.net/geduo_83/article/details/86560896#4.%E7%AE%80%E8%BF%B0View%E7%9A%84%E4%BA%8B%E4%BB%B6%E4%BC%A0%E9%80%92%E6%9C%BA%E5%88%B6%EF%BC%9F>

5.简述ViewGroup的事件传递机制?
<https://blog.csdn.net/geduo_83/article/details/86560896#5.%E7%AE%80%E8%BF%B0ViewGroup%E7%9A%84%E4%BA%8B%E4%BB%B6%E4%BC%A0%E9%80%92%E6%9C%BA%E5%88%B6%3F>

6.事件分发流程图
<https://blog.csdn.net/geduo_83/article/details/86560896#6.%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%E6%B5%81%E7%A8%8B%E5%9B%BE>

7.实战案例
<https://blog.csdn.net/geduo_83/article/details/86560896#4.%E5%AE%9E%E6%88%98%E6%A1%88%E4%BE%8B>

1.在Android操作系统中,拥有事件传递功能的类都有哪些?

* Activity:拥有dispathTouchEvent和onTouchEvent方法
* View:拥有dispathTouchEvent和onTouchEvent方法   
* ViewGroup:拥有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
2.触摸事件的类型?

主要有三种:

* ACTION_DOWN : 手指的按下操作
* ACTION_MOVE:手指按下后,松开手之前,轻微移动所触发的事件
* ACTION_UP:手指离开屏幕的操作
3.事件传递的三个阶段?

* 3.1 按照事件进行划分


* 3.2 按照View进行划分



结论:无论是View还是ViewGroup,不管他是DispatchTouchEvent还是onTouchEvent方法,方法返回true、返回false的处理逻辑都是一样的,只是调用父类的同名方法的时候处理的逻辑有所不同,View偏重消费、ViewGourp偏重分发

4.简述View的事件传递机制?


触摸事件的传递流程是从dispatchTouchEvent开始的,如果不进行人工干预,则事件将会依照View树的嵌套层次从外层向内层传递,到达最内层的View时,就由它的onTouchVent方法处理

如果事件在传递过程中,进行了人工干预,事件分发函数返回true表示自行消费,返回父类的同名方法则该事件传递给自身的onTouchEvent进行处理,返回false表示该事件会回传给父view的onTouchEvent方法进行处理,此时后面的事件都接受不到了,最后由哪个View处理,以后的所有事件都交由它来处理
如果事件在传递过程中,进行了人工干预,事件处理函数,返回true和调用同名方法表示该事件被消费,返回false则表示该事件回传给父类的同名方法进行处理

事件触发是先触发onTouch,再触发onClick,如果onTouch方法返回tue,表示消费掉该事件,不在继续进行事件传递,onClick也不会被调用,如果onTouch方法返回false,则继续会事件传递,onClick会被调用

5.简述ViewGroup的事件传递机制?


触摸事件的传递顺序是由Activity到ViewGroup,再由ViewGroup递归传递给他的子View,ViewGroup通过onInterceptTouchEvent方法对事件进行拦截,如果该方法返回true,则事件不会继续往下传递给子View,如果返回false或者是调用super.onInterceptTouchEvent,则事件会继续会传递给子View

如果事件在传递过程中,进行了人工干预,事件分发函数返回true表示事件被自行消费,返回false,则回传给父View的onTouchEvent进行处理,此时后面的事件都接受不到了,调用同名方法则继续传递
如果事件在传递过程中,进行了人工干预,事件处理函数,返回true则表示该事件被消费,返回false和调用同名方法则表示该事件回传给父类的同名方法进行处理

6.事件分发流程图

一张android事件分发流程,让你彻底搞明白Android的事件分发机制



7.实战案例


实现效果如下,底部的行程详情可以往上拖动覆盖在地图之上,也可以往下拖动停止在屏幕的正中位置,地图相关操作:放大、缩小、移动都能正常的响应,怎么实现?下面就是具体的源码实现过程



* 7.1 事件分发处理 mTransparentView = findViewById(R.id.view_tansparent);
mTransparentView.setListener(new TransparentView.TouchEventListener() {    
@Override     public boolean dispatchTouchEvent(MotionEvent event) {        
return mMapView.dispatchTouchEvent(event);     } }); mScrollView =
findViewById(R.id.view_scrollview); mScrollView.setListener(new
TransparentView.TouchEventListener() {     @Override     public boolean
dispatchTouchEvent(MotionEvent event) {         Rect rect = new Rect();        
mTransparentView.getLocalVisibleRect(rect);        
if(rect.contains((int)event.getX(),(int)event.getY())){             return
true;         }else{             return false;         }     } });
* 7.2 自定义ViewTransparentView public class TransparentView extends View {    
TouchEventListener mListener;     public interface TouchEventListener{        
boolean dispatchTouchEvent(MotionEvent event);     }     public
TransparentView(Context context, @Nullable AttributeSet attrs) {        
super(context, attrs);     }     @Override     public boolean
dispatchTouchEvent(MotionEvent event) {         if(mListener != null){        
    return  mListener.dispatchTouchEvent(event);         }else{            
return super.dispatchTouchEvent(event);         }     }     public void
setListener(TouchEventListener listener) {         mListener = listener;     } }
* 7.3 自定义TransScrollView public class TransScrollView extends
NestedScrollView {     public TransparentView.TouchEventListener mListener;    
public TransScrollView(@NonNull Context context, @Nullable AttributeSet attrs)
{         super(context, attrs);     }     @Override     public boolean
onInterceptTouchEvent(MotionEvent ev) {         if (mListener != null &&
mListener.dispatchTouchEvent(ev)) {             return false;         }        
return super.onInterceptTouchEvent(ev);     }     public void
setListener(TransparentView.TouchEventListener listener) {         mListener =
listener;     } }
* 7.4 布局文件 <FrameLayout     android:layout_width="match_parent"    
android:layout_height="match_parent"     >     <com.amap.api.maps.MapView      
  android:id="@+id/map"         android:layout_width="match_parent"        
android:layout_height="250dp"         />    
<com.zhijiaxing.travel.trip.record.view.TransScrollView        
android:id="@+id/view_scrollview"         android:layout_width="match_parent"  
      android:layout_height="match_parent"         >     <LinearLayout        
android:layout_width="match_parent"        
android:layout_height="wrap_content"         android:orientation="vertical"    
    >         <com.zhijiaxing.travel.trip.record.view.TransparentView          
  android:id="@+id/view_tansparent"            
android:layout_width="match_parent"             android:layout_height="250dp"  
          android:background="#00000000"             />         <LinearLayout  
          android:layout_width="match_parent"            
android:layout_height="wrap_content"             android:background="#ffffff"  
          android:orientation="vertical"             >         </LinearLayout>
    </LinearLayout>    
</com.zhijiaxing.travel.trip.record.view.TransScrollView> </FrameLayout>
 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信