Jetpack 叒一新成员 DragAndDrop 框架:大大简化拖放手势开发

简介: Jetpack 叒一新成员 DragAndDrop 框架:大大简化拖放手势开发

对于拖放功能,大家并不陌生,这是在桌面端最稀松平常的操作,比如将文件拖入回收站。随着移动设备的大屏趋势、可折叠设备的愈加发完善,拖放操作在移动平台里端也显得愈加必要和流行!


针对拖放功能的实现,Android 平台现存的方案略为复杂。基于此, Jetpack 框架集合里推出了新成员 DragAndDrop 。


本文着重阐述该框架的愿景和核心要点,主要内容译自 Android 开发者关系工程师 Paul 在 Meduim 上的 Post:Simplifying drag and drop。


本质来说,拖放手势(drag and drop)指的是用户通过点击选择图片、文本或者其他数据元素,然后直接拖放到 App 的其他界面、甚至其他 App 的界面,接着这个数据就被纳入到新的界面内。这个手势通常表现为在触摸屏上的长按拖动或者非触摸屏上的单击并用鼠标拖动,最后在目标位置`放下。


来看一个 App 内典型的拖放效果:

image.gif

尽管 Android 一直长期支持拖放功能的实现(比如早在 Android 3.0 即加入的 DragEvent API),但事实证明:想要完整、顺畅地实现针对过程中的手势、触摸事件、权限以及回调的集成,往往比较困难和复杂。


现在我想向大家推荐 Jetpack 的新成员 DragAnd Drop 框架,目前处于 alpha 版本,其旨在辅助你更加简单地处理拖放 App 内的数据。

在 build.gradle 里引入依赖,即可使用。

implementation 'androidx.draganddrop:draganddrop:1.0.0-alpha02'

拖放功能的使用在大屏设备上日益频繁,比如平板电脑和笔记本电脑,尤其是可折叠设备。在这种类型的设备上进行分屏的操作比传统的智能手机多了高达 7 倍。他们的用户常常需要使用分屏或多窗口(https://developer.android.com/guide/topics/large-screens/multi-window-support) 模式来处理多任务的场景,而将数据在不同的 App 间拖放是再自然不过的体验和需求!


Android 平台原生已经支持从输入框控件 EditText 拖动文本,但我们强烈建议开发者实现用户从其他控件拖动数据的功能,支持的数据类型除了文本以外,还能包括图片、文件等任意类型。当然了,反向支持数据从其他 App 拖放进来也同等重要,并值得鼓励。


来看一个 App 之间拖放文本和图片的示例效果:

image.gif

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 = 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.
  ...
}

了解更多

如上只是精简的介绍,更多细节可以到如下的官方文档进行详细地了解:


拖放功能的官方文档:https://developer.android.com/guide/topics/ui/drag-drop

当然,也可以通过官方的完备 DEMO 进行更深入地学习和实践:


官方 DEMO 地址:https://github.com/android/user-interface-samples/tree/main/DragAndDropAcrossApps

还有一点尤为重要,记得在 Android Issue 网站反馈你遇到的 Bug 或意见:


https://issuetracker.google.com/issues/new?component=1139019

最后,如果你觉得我的阐述存在难以理解的地方,不妨阅读本文翻译的原文:


原文地址:Simplifying drag and drop


相关文章
|
2月前
|
安全 Java Android开发
安卓开发中的新趋势:Kotlin与Jetpack的完美结合
【6月更文挑战第20天】在不断进化的移动应用开发领域,Android平台以其开放性和灵活性赢得了全球开发者的青睐。然而,随着技术的迭代,传统Java语言在Android开发中逐渐显露出局限性。Kotlin,一种现代的静态类型编程语言,以其简洁、安全和高效的特性成为了Android开发中的新宠。同时,Jetpack作为一套支持库、工具和指南,旨在帮助开发者更快地打造优秀的Android应用。本文将探讨Kotlin与Jetpack如何共同推动Android开发进入一个新的时代,以及这对开发者意味着什么。
|
2月前
|
数据管理 API 数据库
探索Android Jetpack:现代安卓开发的利器
Android Jetpack是谷歌为简化和优化安卓应用开发而推出的一套高级组件库。本文深入探讨了Jetpack的主要构成及其在应用开发中的实际运用,展示了如何通过使用这些工具来提升开发效率和应用性能。
|
22天前
|
存储 数据库 Android开发
🔥Android Jetpack全解析!拥抱Google官方库,让你的开发之旅更加顺畅无阻!🚀
【7月更文挑战第28天】在Android开发中追求高效稳定的路径?Android Jetpack作为Google官方库集合,是你的理想选择。它包含多个独立又协同工作的库,覆盖UI到安全性等多个领域,旨在减少样板代码,提高开发效率与应用质量。Jetpack核心组件如LiveData、ViewModel、Room等简化了数据绑定、状态保存及数据库操作。引入Jetpack只需在`build.gradle`中添加依赖。例如,使用Room进行数据库操作变得异常简单,从定义实体到实现CRUD操作,一切尽在掌握之中。拥抱Jetpack,提升开发效率,构建高质量应用!
40 4
|
1月前
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
2月前
|
安全 JavaScript 前端开发
kotlin开发安卓app,JetPack Compose框架,给webview新增一个按钮,点击刷新网页
在Kotlin中开发Android应用,使用Jetpack Compose框架时,可以通过添加一个按钮到TopAppBar来实现WebView页面的刷新功能。按钮位于右上角,点击后调用`webViewState?.reload()`来刷新网页内容。以下是代码摘要:
|
2月前
|
JavaScript Java Android开发
kotlin安卓在Jetpack Compose 框架下跨组件通讯EventBus
**EventBus** 是一个Android事件总线库,简化组件间通信。要使用它,首先在Gradle中添加依赖`implementation &#39;org.greenrobot:eventbus:3.3.1&#39;`。然后,可选地定义事件类如`MessageEvent`。在活动或Fragment的`onCreate`中注册订阅者,在`onDestroy`中反注册。通过`@Subscribe`注解方法处理事件,如`onMessageEvent`。发送事件使用`EventBus.getDefault().post()`。
171 2
|
2月前
|
JavaScript 前端开发 Android开发
kotlin安卓在Jetpack Compose 框架下使用webview , 网页中的JavaScript代码如何与native交互
在Jetpack Compose中使用Kotlin创建Webview组件,设置JavaScript交互:`@Composable`函数`ComposableWebView`加载网页并启用JavaScript。通过`addJavascriptInterface`添加`WebAppInterface`类,允许JavaScript调用Android方法如播放音频。当页面加载完成时,执行`onWebViewReady`回调。
|
2月前
|
缓存 Android开发 Kotlin
【安卓app开发】kotlin Jetpack Compose框架 | 先用OKhttp下载远程音频文件再使用ExoPlayer播放
使用 Kotlin 的 Jetpack Compose 开发安卓应用时,可以结合 OkHttp 下载远程音频文件和 ExoPlayer 进行播放。在 `build.gradle` 添加相关依赖后,示例代码展示了如何下载音频并用 ExoPlayer 播放。代码包括添加依赖、下载文件、播放文件及简单的 Compose UI。注意,示例未包含完整错误处理和资源释放,实际应用需补充这些内容。
129 5
|
2月前
|
安全 网络安全 API
kotlin安卓开发JetPack Compose 如何使用webview 打开网页时给webview注入cookie
在Jetpack Compose中使用WebView需借助AndroidView。要注入Cookie,首先在`build.gradle`添加WebView依赖,如`androidx.webkit:webkit:1.4.0`。接着创建自定义`ComposableWebView`,通过`CookieManager`设置接受第三方Cookie并注入Cookie字符串。最后在Compose界面使用这个自定义组件加载URL。注意Android 9及以上版本可能需要在网络安全配置中允许第三方Cookie。
278 0
|
2月前
|
Android开发 Kotlin
kotlin安卓开发【Jetpack Compose】:封装SnackBarUtil工具类方便使用
GPT-4o 是一个非常智能的模型,比当前的通义千问最新版本在能力上有显著提升。作者让GPT开发一段代码,功能为在 Kotlin 中使用 Jetpack Compose 框架封装一个 Snackbar 工具类,方便调用
107 0