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

学更好的别人,

做更好的自己。

——《微卡智享》

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第1张图片

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

前言

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

0e70bed1961ca867944c1b789dd88c65.png

实现效果

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

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的名称。

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第2张图片

拖拽效果

//设置拖拽效果
        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(),开启监听

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第3张图片

拖拽释放

//拖拽放下效果
        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
 * 邮箱:[email protected]
 * 创建时间:14:49
 * 功能模块说明:
 */
class DrugsAdapterNew(layoutId: Int, drugslist: MutableList? = null) :
    BaseQuickAdapter(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的监听了,方便很多。

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第4张图片

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

对比

df18df76c586d012757cfba1fd6187e7.png

微卡智享

旧版DragAndDrop

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

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第5张图片

2.  在Adapter中要设置DragListener

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第6张图片

JetPack的DragAndDrop

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

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第7张图片

效果对比

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第8张图片

源码地址

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

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

7850d18aa7b96ad56d790a8d7bccdf71.png

ea13c3e7e0be98f758eb98791f2814db.png

往期精彩回顾

Android JetPack--拖拽DragAndDrop使用及和旧版对比_第9张图片

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


Android JetPack--拖拽DragAndDrop使用及和旧版对比_第10张图片

OpenCV实现图片批号效期提取


Android JetPack--拖拽DragAndDrop使用及和旧版对比_第11张图片

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


你可能感兴趣的:(java,python,android,vue,安卓)