android安全处理流程图,Android事件分发机制详解与实战剖析,一张事件分发流程图,让你彻底搞明白...

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

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

目录

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

[2.触摸事件的类型?]

[3.事件传递的三个阶段?]

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

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

[6.事件分发流程图]

[7.实战案例]

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

Activity:拥有dispathTouchEvent和onTouchEvent方法

View:拥有dispathTouchEvent和onTouchEvent方法

ViewGroup:拥有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent

2.触摸事件的类型?

主要有三种:

ACTION_DOWN : 手指的按下操作

ACTION_MOVE:手指按下后,松开手之前,轻微移动所触发的事件

ACTION_UP:手指离开屏幕的操作

3.事件传递的三个阶段?

3.1 按照事件进行划分

b173ada7b496

image

3.2 按照View进行划分

b173ada7b496

image

结论:无论是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的事件分发机制

b173ada7b496

image

ViewGroup的事件分发的伪代码:

public boolean dispatchTouchEvent(MotionEvent ev) {

boolean consume = false;

if (onInterceptTouchEvent(ev)) {

if (!(mOnTouchListener != null && mOnTouchListener.onTouchEvent(ev))) {

consume = onTouchEvent(ev);

}

} else {

consume = child.dispatchTouchEvent(ev);

}

return consume;

}

public void onTouchEvent(MotionEvent ev) {

boolean consume = false;

if (mOnClickListener != null) {

mOnClickListener.onClick(this);

consume = true;

}

return consume;

}

View的事件分发的伪代码:

public boolean dispatchTouchEvent(MotionEvent ev) {

boolean consume = false;

consume = onTouchEvent(ev);

return consume;

}

public void onTouchEvent(MotionEvent ev) {

boolean consume = false;

if (mOnClickListener != null) {

mOnClickListener.onClick(this);

consume = true;

}

return consume;

}

7.实战案例

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

b173ada7b496

image

b173ada7b496

image.gif

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;

}

}

b173ada7b496

image.gif

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;

}

}

b173ada7b496

image.gif

7.4 布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

>

android:id="@+id/map"

android:layout_width="match_parent"

android:layout_height="250dp"

/>

android:id="@+id/view_scrollview"

android:layout_width="match_parent"

android:layout_height="match_parent"

>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

>

android:id="@+id/view_tansparent"

android:layout_width="match_parent"

android:layout_height="250dp"

android:background="#00000000"

/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="#ffffff"

android:orientation="vertical"

>

b173ada7b496

image.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值