对于来看一个 App 内典型的拖放效果:拖放
手势,大家并不陌生,这是在桌面端最稀松平常的操作,比如将文件拖入回收站。随着移动设备的大屏趋势、可折叠设备的愈加发完善,拖放操作在移动平台里端也显得愈加必要和流行!
实现拖放手势: Android 平台现存的方案略为复杂。基于此,Jetpack
框架集合里推出了新成员DragAndDrop
。
_本文着重阐述该框架的愿景和核心要点,主要内容译自 Android 开发者关系工程师Paul
在Meduim
上的 Post
本质来说,拖放
手势(drag and drop)指的是用户通过点击选择图片、文本或者其他数据元素,然后直接拖放到 App 的其他界面、甚至其他 App 的界面,接着这个数据就被纳入到新的界面内。这个手势通常表现为在触摸屏上的长按拖动
或者非触摸屏上的单击并用鼠标拖动
,最后在目标位置放下
。
尽管 Android 一直长期支持拖放手势的实现(比如早在 Android
3.0
即加入的 DragEvent
API),但事实证明:想要完整、顺畅地实现针对过程中的手势
、触摸事件
、权限
以及回调
的集成,往往比较困难和复杂。现在我想向大家推荐 Jetpack 的新成员 DragAnd Drop 框架",目前处于
alpha
版本,其旨在辅助你更加简单地处理拖放 App 内的数据。在 build.gradle 里引入依赖,即可使用。
implementation 'androidx.draganddrop:draganddrop:1.0.0-alpha02'
拖放手势的使用在
大屏设备
上日益频繁,比如平板电脑和笔记本电脑,尤其是可折叠
设备。在这种类型的设备上进行分屏的操作比传统的智能手机多了高达 7 倍。他们的用户常常需要使用分屏
或多窗口
模式来处理多任务
的场景,而将数据在不同的 App 间拖放是再自然不过的体验和需求!Android 平台原生已经支持从输入框控件
EditText
拖动文本,但我们强烈建议开发者实现用户从其他控件拖动数据的手势,支持的数据类型除了文本以外,还能包括图片、文件等任意类型。当然了,反向支持数据从其他 App 拖放进来也同等重要,并值得鼓励。来看一个 App 之间拖放文本和图片的示例效果:
DragStartHelper
,结合 DropHelper
构成了整个框架最核心的 API,它们可以轻松实现手势支持、数据的回调、样式和像素级的 UI 对齐等实现环节。DragStartHelper 作为 Jetpack 框架集合
core
包下的工具类, DragStartHelper
负责监测拖动手势的开始时机。这些手势包括长按拖动、单击并用鼠标拖动等。使用起来很简单,将需要监听的视图包装进来并开始监听。框架会在拖动手势触发的时候回调过来,之后进行一些简单的配置即可。
- 将需要传递的数据包装到
ClipData
中 - 新建用于展示拖动效果的图片实例
DragShadowBuilder
- 将数据和拖动效果外加一些 Flag 交由 View 的原生方法
startDragAndDrop()
进行后续的动作,包括效果的展示和数据的传递等
// Make a view draggable to share a file. DragStartHelper takes care of
// intercepting drag gestures and attaching the listener.
DragStartHelper(draggableView) { view, _ ->
// Sets the appropriate MIME types automatically.
val dragClipData = https://www.it610.com/article/ClipData.newUri(contentResolver,"File", fileUri)// Set the visual look of the dragged object.
// Can be extended and customized;
we use the default here.
val dragShadow = View.DragShadowBuilder(view)// Starts the drag. Note that the global flag allows for cross-app dragging.
view.startDragAndDrop(
dragClipData,
dragShadow,
null, // Optional extra local state information
// Since this is a "content:" URI and not just plain text, we can use the
// DRAG_FLAG_GLOBAL_URI_READ to allow other apps to read from our content
// provider. Without it, other apps won't receive the drag events.
DRAG_FLAG_GLOBAL or DRAG_FLAG_GLOBAL_URI_READ)
)
}.attach()
DropHelper 另一个核心工具类
DropHelper
,则关心拖动数据放下的时机和目标视图。适配的代码简单来讲:
- 需要针对可拖放数据的试图调用
configureView
方法 - 其内部还需要设定关心的数据类型即
Mime Type
- 指定一些其他可选参数实例
DropHelper.Options
,比如放下时高亮的颜色和视图范围等 - 最后设置最重要的放下监听器
OnReceiveContentListener
,去从 ClipData 中取得数据执行上传、显示等处理,当然还包括不匹配的警告或视图提醒等
DropHelper.Options
实例的时候,记得调用 addInnerEditTexts()
,这样可以确保嵌套的 EditText 控件不会抢夺视图焦点。DropHelper.configureView(
// Activity that will handle the drop
this,
// Target drop view to be highlighted
outerDropTarget,
// Supported MIME types
arrayOf(MIMETYPE_TEXT_PLAIN, "image/*"),
// Options for configuring drop targets
DropHelper.Options.Builder()
// To ensure proper drop target highlighting, all EditText elements in
// the drop target view hierarchy must be included in a call to this
// method. Otherwise, an EditText within the target, rather than the
// target view itself, acquires focus during the drag and drop operation.
.addInnerEditTexts(innerEditText)
.build()
) { _, payload ->
// Process the payload here, returning any content that should be delegated to
// the platform.
...
}
相关教程 Android基础系列教程:
Android基础课程U-小结_哔哩哔哩_bilibili
Android基础课程UI-布局_哔哩哔哩_bilibili
Android基础课程UI-控件_哔哩哔哩_bilibili
Android基础课程UI-动画_哔哩哔哩_bilibili
Android基础课程-activity的使用_哔哩哔哩_bilibili
Android基础课程-Fragment使用方法_哔哩哔哩_bilibili
Android基础课程-热修复/热更新技术原理_哔哩哔哩_bilibili
【Jetpack 叒一新成员 DragAndDrop 框架(大大简化拖放手势开发!)】本文转自 https://juejin.cn/post/7043616310369976328,如有侵权,请联系删除。
推荐阅读
- 备战金三银四,没有这套逆天的Android面经怎么行()
- 如何学习Flutter(学会这些你就入门了)
- 音视频人才的需求从小众变成了大众(一名合格的音视频开发人员,少则30万起,多则年薪可达百万以上......)
- 什么是“好”的技术(为什么“火”?)
- Android项目实战(浅谈ListView悬浮头部展现效果)
- 什么是音频焦点管理(音频焦点的行为准则是什么?)
- 知乎热议(35岁的中年危机,大龄程序员该何去何从())
- 安卓点击防抖优化手册(非代码层指导)
- 太卷了,公司新来的00后卷王,我们这帮老油条真干不过.....
- 那些年,被我们误解的程序员