Android JetPack--拖拽DragAndDrop使用及和旧版对比

学更好的别人,

做更好的自己。

——《微卡智享》

b833be2c1e277d62e07704c8c228c17c.png

本文长度为2849,预计阅读6分钟

前言

上一篇《Android使用DragAndDrop拖拽效果实现宫格位置变换》中主要介绍DragAndDrop拖拽组件,并做了一个使用的Demo,在Jetpack中将DragAndDrop再做了一次简化,使用起来更加的简单了。现在出的是alpha的版本,不影响我们学习一下使用。

0e70bed1961ca867944c1b789dd88c65.png

实现效果

991f9a2408e84b1dc158ac068aa4f99e.gif

从动图上效果其实和昨天的一样,只不过拖拽的过程中可以看到有阴影的效果,从动图中其实也可以看到,反复操作的时候偶尔会有阴影的效果在释放后并没有消除,正式版出来后应该就不会有这样的问题了吧。

Jetpack DragAndDrop简介

1371190917ea1002f06bf52d015cb7b3.png

微卡智享

初始版本的功能

DropHelper 是 draganddrop 库的第一个成员,也是一个实用程序类,有助于简化拖放功能的实现。您可以使用 DropHelper 来指定拖放目标、自定义拖放目标突出显示效果,以及定义如何处理用户放下的数据。

DropHelper 利用 Jetpack 的 OnReceiveContentListener 来提供针对特定目标的拖放 ClipData 处理功能。DropHelper 可通过配置拖放目标,在用户将内容拖到目标上时显示突出显示效果,从而有助于提升用户体验。借助 DropHelper.Options 嵌套类,您可以自定义默认突出显示效果的颜色和圆角半径。

借助 DropHelper.Options,您还可以列出复杂拖放目标的视图层次结构中包含的所有 EditText 元素。当用户将数据拖到目标上时,DropHelper 可防止 EditText 元素从拖放目标窃取焦点。如果拖放 ClipData 包含文本和 URI 数据,当用户放下 ClipData 时,DropHelper 会选择拖放目标中的一个 EditText 元素来处理文本数据。

6308328500ddb605828b9a0582d2c728.png

上面是Google的官方介绍,想要实现我们动图上的效果,只要做两步即可

  1. DragStartHelper实现拖拽的效果

  2. DropHelper.configureView实现释放拖拽时的逻辑

代码实现

03291ba1686bfead57f27d4b4193fcb7.png

微卡智享

程序还是上一篇我们的Demo,在原来的DrugsAdapter复制出来,重新加一个New的名称。

05e18063d6702b517112ea47ef5f64d0.png

拖拽效果

//设置拖拽效果
        DragStartHelper(
            holder.itemView
        ) { v, helper ->
            //定义Intent
            val intent = Intent()
            intent.putExtra("pos", holder.adapterPosition)
            val dragdata = ClipData.newIntent("olditem", intent)
            val shadow: View.DragShadowBuilder = View.DragShadowBuilder(v)
            v.startDragAndDrop(dragdata, shadow, null, 0)
        }.attach()

DragStartHelper里面参数就是我们的View,后面的Lambda就是实现过程,最后记得要加上attach(),开启监听

38bcbb887cff6a7bda67feb5d1a7b124.png

拖拽释放

//拖拽放下效果
        DropHelper.configureView(
            this.context as Activity, holder.itemView,
            arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT, "olditem")
        ) { view, payload ->
            val intent = payload.clip.getItemAt(0).intent
            val oldpos = intent.getIntExtra("pos", -1)
            //记录现在格的数据


            val nowpos = view?.getTag() as Int
            //将现在格数据存到临时变量中
            val nowitem = CDrugs()
            nowitem.drugs_ckcode = data[nowpos].drugs_ckcode
            nowitem.drugs_code = data[nowpos].drugs_code
            nowitem.drugs_name = data[nowpos].drugs_name
            nowitem.drugs_specs = data[nowpos].drugs_specs
            nowitem.qty = data[nowpos].qty


            //修改现在格的数据
            data[nowpos].drugs_ckcode = nowitem.drugs_ckcode;
            data[nowpos].drugs_code = data[oldpos].drugs_code
            data[nowpos].drugs_name = data[oldpos].drugs_name
            data[nowpos].drugs_specs = data[oldpos].drugs_specs
            data[nowpos].qty = data[oldpos].qty


            //修改原来的格数据
            data[oldpos].drugs_code = nowitem.drugs_code
            data[oldpos].drugs_name = nowitem.drugs_name
            data[oldpos].drugs_specs = nowitem.drugs_specs
            data[oldpos].qty = nowitem.qty


            notifyItemChanged(nowpos)
            notifyItemChanged(oldpos)


            return@configureView ContentInfoCompat.Builder(
                payload.clip,
                ContentInfoCompat.SOURCE_APP
            ).build()
        }

DropHelper.configureView中第一个参数是activity,本身adapter中没有传递这个进来,所以我用的this.context as activity转换了一下,第二个参数就View,第三个参数是mimeTypes类型

lambda表达式本身也是onReceiveContent方法的实现,里面的逻辑和昨天是一样的,只不过函数要最后返回ContentInfoCompat,所以这里直接用ContentInfoCompat.Builder实现了。

DrugsAdapterNew完整代码

package pers.vaccae.draganddropdemo.adapter


import android.app.Activity
import android.content.ClipData
import android.content.ClipDescription
import android.content.Intent
import android.view.DragEvent
import android.view.View
import androidx.core.view.ContentInfoCompat
import androidx.core.view.DragStartHelper
import androidx.draganddrop.DropHelper
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import pers.vaccae.draganddropdemo.R
import pers.vaccae.draganddropdemo.bean.CDrugs




/**
 * 作者:Vaccae
 * 邮箱:3657447@qq.com
 * 创建时间:14:49
 * 功能模块说明:
 */
class DrugsAdapterNew(layoutId: Int, drugslist: MutableList<CDrugs>? = null) :
    BaseQuickAdapter<CDrugs, BaseViewHolder>(layoutId, drugslist) {


    override fun convert(holder: BaseViewHolder, item: CDrugs) {
        holder.setText(R.id.rcl_drugs_ckcode, item.drugs_ckcode.toString())
        holder.setText(R.id.rcl_drugs_code, item.drugs_code)
        holder.setText(R.id.rcl_drugs_name, item.drugs_name)
        holder.setText(R.id.rcl_drugs_specs, item.drugs_specs)
        holder.setText(R.id.rcl_qty, item.qty.toString())


        holder.itemView.setTag(holder.adapterPosition)


        //设置拖拽效果
        DragStartHelper(
            holder.itemView
        ) { v, helper ->
            //定义Intent
            val intent = Intent()
            intent.putExtra("pos", holder.adapterPosition)
            val dragdata = ClipData.newIntent("olditem", intent)
            val shadow: View.DragShadowBuilder = View.DragShadowBuilder(v)
            v.startDragAndDrop(dragdata, shadow, null, 0)
        }.attach()


        //拖拽放下效果
        DropHelper.configureView(
            this.context as Activity, holder.itemView,
            arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT, "olditem")
        ) { view, payload ->
            val intent = payload.clip.getItemAt(0).intent
            val oldpos = intent.getIntExtra("pos", -1)
            //记录现在格的数据


            val nowpos = view?.getTag() as Int
            //将现在格数据存到临时变量中
            val nowitem = CDrugs()
            nowitem.drugs_ckcode = data[nowpos].drugs_ckcode
            nowitem.drugs_code = data[nowpos].drugs_code
            nowitem.drugs_name = data[nowpos].drugs_name
            nowitem.drugs_specs = data[nowpos].drugs_specs
            nowitem.qty = data[nowpos].qty


            //修改现在格的数据
            data[nowpos].drugs_ckcode = nowitem.drugs_ckcode;
            data[nowpos].drugs_code = data[oldpos].drugs_code
            data[nowpos].drugs_name = data[oldpos].drugs_name
            data[nowpos].drugs_specs = data[oldpos].drugs_specs
            data[nowpos].qty = data[oldpos].qty


            //修改原来的格数据
            data[oldpos].drugs_code = nowitem.drugs_code
            data[oldpos].drugs_name = nowitem.drugs_name
            data[oldpos].drugs_specs = nowitem.drugs_specs
            data[oldpos].qty = nowitem.qty


            notifyItemChanged(nowpos)
            notifyItemChanged(oldpos)


            return@configureView ContentInfoCompat.Builder(
                payload.clip,
                ContentInfoCompat.SOURCE_APP
            ).build()
        }
    }
}

这里可以看到,在Adapter的convert中直接加入拖拽的实现和释放的两步就可以,不需要再写什么继承onDragLister的监听了,方便很多。

efc9949d73e67b14040ecde199bc229a.png

MainActivity中将原来的DrugsAdapter改为DrugsAdapterNew就完成了。

对比

df18df76c586d012757cfba1fd6187e7.png

微卡智享

旧版DragAndDrop

1.  需要写 View.OnDragListener监听,因为实现中要修改adapter,所以实例化时还要传入adapter参数,如果不传参数需要类似LiveEventBus等消息组件进行通知,或是写回调修改。

c28a4a7e0b257e0ec133cce03e17d444.png

2.  在Adapter中要设置DragListener

13c4aff29e87a7f38bf8d8cfd33baf29.png

JetPack的DragAndDrop

无需单独写监听,直接写DragStartHelper和DropHelper.configureView的逻辑即可

eb8ff4262bcf2d13d55f144de0cd95af.png

效果对比

2395c7cf60abbda74e77633f87222a8d.png

f392a85c55178ed130e928f62cc45a0b.gif

源码地址

https://github.com/Vaccae/Android-DragAndDropDemo.git

点击原文链接可以跳转到“码云”的下载地址

7850d18aa7b96ad56d790a8d7bccdf71.png

ea13c3e7e0be98f758eb98791f2814db.png

往期精彩回顾

2692cb2627d36d2fabbc503011b13ae2.png

Android使用DragAndDrop拖拽效果实现宫格位置变换


850712ed7c3286710a28384b35c81781.png

OpenCV实现图片批号效期提取


0ad7c75ad9f9be21430e3cb8e78a8460.png

OpenCV图像锐化---USM锐化和Laplace锐化


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vaccae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值