当前位置:网站首页>Drag and drop拖放框架
Drag and drop拖放框架
2022-06-23 03:55:00 【xhBruce】
Drag and drop拖放框架
android11-release
应用使用 拖放 Drag and drop
Drag and drop拖放启动
APP调用启动
拖放 Drag and dropstartDragAndDrop 启动
frameworks/base/core/java/android/view/View.java
frameworks\base\services\core\java\com\android\server\wm\Session.java
初始化DragState并注册InputChannel
- 初始化DragState
- 注册
drag InputChannel\DragInputEventReceiver - 通知拖放开始
mDragState.broadcastDragStartedLocked(touchX, touchY);触发DragEvent.ACTION_DRAG_STARTED
frameworks/base/services/core/java/com/android/server/wm/DragDropController.java
frameworks/base/services/core/java/com/android/server/wm/DragState.java
frameworks/base/services/core/java/com/android/server/wm/WindowManagerInternal.java
frameworks/base/services/core/java/com/android/server/wm/DragInputEventReceiver.java


最后notifyLocationLocked
(touchedWin != mTargetWindow) && (mTargetWindow != null)时触发DragEvent.ACTION_DRAG_EXITEDtouchedWin != null时触发DragEvent.ACTION_DRAG_LOCATION
- 通过
ViewRootImplmpl层层调用,result = mView.dispatchDragEvent(event)通知APP并接受返回值 li.mOnDragListener.onDrag(this, event)真正通知APP
frameworks/base/core/java/android/view/ViewRootImpl.java
frameworks/base/core/java/android/view/View.java



Drag and drop拖放启动小结:
- APP启动
startDragAndDrop,并View.OnDragListener监听 - 初始化
DragState和注册drag InputChannel\DragInputEventReceiver; - ViewRootImpl中
result = mView.dispatchDragEvent(event);发送到View,这里注意返回值result - View中
li.mOnDragListener.onDrag(this, event)通知到APP监听 SurfaceControl控制显示Surface,该显示与一般WMS显示不同
Drag and drop拖放action触发问题
public static final int ACTION_DRAG_STARTED = 1;
public static final int ACTION_DRAG_LOCATION = 2;
public static final int ACTION_DROP = 3;
public static final int ACTION_DRAG_ENDED = 4;
public static final int ACTION_DRAG_ENTERED = 5;
public static final int ACTION_DRAG_EXITED = 6;
- ACTION_DRAG_STARTED
当应用调用 startDragAndDrop\startDrag 并获取拖动阴影后,视图对象的拖动事件监听器会立即收到此事件操作类型。
1 触发
上面也看到初始化registerInputChannel完成后mDragState.broadcastDragStartedLocked(touchX, touchY)通知完成:performDrag -> broadcastDragStartedLocked -> sendDragStartedLocked -> newWin.mClient.dispatchDragEvent(event)\dispatchDragEvent(DragEvent event) -> handleDragEvent
2 通知APP监听前操作
frameworks/base/core/java/android/view/ViewRootImpl.java
handleDragEvent 中设置mCurrentDragView = null;mDragDescription保存 event.mClipDescription
3 result = mView.dispatchDragEvent(event)返回值
result 无论返回 true 或 false 没有其他处理,所有没有其他影响。
- ACTION_DRAG_LOCATION
当收到 ACTION_DRAG_ENTERED 事件且拖动阴影仍在视图的边界框内时,该视图对象的拖动事件监听器会收到此事件操作类型。
1 触发
这里注册了
drag InputChannel\DragInputEventReceiver,收到ACTION_MOVE事件调用mDragDropController.handleMotionEvent(Android 12 beta4这里没有任何操作),!mMuteInput最终调用到mDragState.notifyMoveLocked。
frameworks/base/services/core/java/com/android/server/wm/DragInputEventReceiver.java
frameworks/base/services/core/java/com/android/server/wm/DragDropController.java
frameworks/base/services/core/java/com/android/server/wm/DragState.java

在 DragState中notifyLocationLocked 通过
touchedWin.mClient.dispatchDragEvent(evt)调用到ViewRootImpl中handleDragEvent

流程小结:drag InputChannel\DragInputEventReceiver -> handleMotionEvent -> notifyMoveLocked\notifyLocationLocked -> touchedWin.mClient.dispatchDragEvent(evt)\dispatchDragEvent(DragEvent event) -> handleDragEvent
2 通知APP监听前操作
frameworks/base/core/java/android/view/ViewRootImpl.java

3 result = mView.dispatchDragEvent(event)返回值
result 无论返回 true 或 false,!event.mEventHandlerWasCalled判断执行setDragFocus。

- ACTION_DROP
当用户将拖动阴影释放到视图对象上时,该视图对象的拖动事件监听器会收到此事件操作类型。仅当视图对象的监听器在响应 ACTION_DRAG_STARTED 拖动事件时返回布尔值 true 时,系统才会将该操作类型发送至该监听器。如果用户将拖动阴影释放到未注册监听器的视图上或不属于当前布局的任何视图上,系统都不会发送此操作类型。
如果成功处理了放下操作,监听器应返回布尔值 true。否则,它应返回 false。
1 触发
这里注册了
drag InputChannel\DragInputEventReceiver,收到ACTION_UP\ACTION_CANCEL事件调用mDragDropController.handleMotionEvent(Android 12 beta4这里没有任何操作),!mMuteInput最终调用到mDragState.notifyDropLocked。
在 DragState中notifyLocationLocked 通过
touchedWin.mClient.dispatchDragEvent(evt)调用到ViewRootImpl中handleDragEvent

流程小结:drag InputChannel\DragInputEventReceiver -> handleMotionEvent -> notifyMoveLocked\notifyLocationLocked -> touchedWin.mClient.dispatchDragEvent(evt)\dispatchDragEvent(DragEvent event) -> handleDragEvent
与
ACTION_DRAG_LOCATION不同的是这里超时5s执行mDragState.endDragLocked()


这里也可能不会触发
DragEvent.ACTION_DROP,closeLocked()结束触发DragEvent.ACTION_DRAG_ENDED


2 通知APP监听前操作
frameworks/base/core/java/android/view/ViewRootImpl.java

3 result = mView.dispatchDragEvent(event)返回true情况
APP返回true结束拖放closeLocked()结束触发DragEvent.ACTION_DRAG_ENDED


- ACTION_DRAG_ENDED
当系统结束拖动操作时,视图对象的拖动事件监听器会收到此事件操作类型。
此操作类型不一定在 ACTION_DROP 事件之后。
如果系统已发送 ACTION_DROP,收到 ACTION_DRAG_ENDED 操作类型并不表示放下操作成功。
监听器必须调用 getResult() 才能获得响应 ACTION_DROP 时所返回的值。
如果未发送 ACTION_DROP 事件,getResult() 将返回 false。
1 触发
读到这里,上面可看到closeLocked()方法触发DragEvent.ACTION_DRAG_ENDED
这里先注销drag input channel
2 通知APP监听前操作

3 result = mView.dispatchDragEvent(event)返回值
result 无论返回 true 或 false都重置
- ACTION_DRAG_ENTERED\ACTION_DRAG_EXITED
**ACTION_DRAG_ENTERED**当拖动阴影刚进入视图的边界框时,视图对象的拖动事件监听器会收到此事件操作类型。这是监听器在拖动阴影进入边界框时收到的第一个事件操作类型。如果监听器想继续接收此操作的拖动事件,必须向系统返回布尔值 true。
**ACTION_DRAG_EXITED**当收到 ACTION_DRAG_ENTERED 和至少一个 ACTION_DRAG_LOCATION 事件,并且用户已将拖动阴影移至视图的边界框以外时,该视图对象的拖动事件监听器会收到此事件操作类型。
1 触发
从上面看到setDragFocus设置刷新时会触发
2 直接调用callDragEventHandler
ACTION_DRAG_ENTERED 说明返回 true,目前没有看到为什么
边栏推荐
- Cookie-Session讲解
- "Wechat applet - Basics" takes you to understand the routing system of the applet (2)
- 【Leetcode】最长递增子序列问题及应用
- Notepad++ find replace group replace retain
- STP summary
- Open source ecology 𞓜 super practical open source license basic knowledge literacy post (Part 2)
- UI automation positioning edge -xpath actual combat
- 三层架构实验
- A compiler related bug in rtklib2.4.3 B34
- UI自动化定位利器-xpath实战
猜你喜欢

"Wechat applet - Basics" takes you to understand the routing system of the applet (2)

Chrome debugging tips

功能测试人员如何做到花一个月的时间进阶自动化软件测试工程师

UI自动化定位利器-xpath实战

LeetCode 797:所有可能的路径

工作5-8年的外包测试员,平均年薪有多少?

微信小程序:老年祝福短视频

C'est dur de trouver un emploi? Ali des trois côtés, heureusement qu'il s'est bien préparé et qu'il a pris un produit.

李宏毅《机器学习》丨5. Tips for neural network design(神经网络设计技巧)

Beyond chips and AI, why is hard technology capital becoming more and more "hard core"?
随机推荐
笔者认为所谓的产业互联网,就是一个产业与互联网深度融合的过程
STP summary
SwiftUI 2.0 课程笔记 Chapter 4
Unity中,如何在【编辑器】和【运行时】状态下读写一个ScriptableObject对象
[laravel series 7.8] broadcasting system
【图像融合】基于非凸罚分的稀疏正则化实现图像融合附matlab代码
大环境不好难找工作?三面阿里,幸好做足了准备,已拿offer
A compiler related bug in rtklib2.4.3 B34
JSP入门级笔记
One or more lines of text overflow, ellipsis instead
使用PX4的ECL进行多传感器数据融合的后处理
Arduino火焰传感器(含代码)
大環境不好難找工作?三面阿裏,幸好做足了准備,已拿offer
UI自动化定位利器-xpath实战
【Laravel系列7.8】广播系统
1183. electricity
MySQl基础
微信小程序;AI智能配音助手
开源生态|超实用开源License基础知识扫盲帖(下)
GNSS速度解算的三种方法