欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发教程拖动删除(仿微信朋友圈拖动删除)

程序员文章站 2022-04-18 22:32:47
Android开发教程拖动删除(仿微信朋友圈拖动删除)。 1 示例 发朋友圈的时候,长按图片可以调整顺序,还可以拖动到底部删除。 2 官方示例: https://d...

Android开发教程拖动删除(仿微信朋友圈拖动删除)。

1 示例

Android开发教程拖动删除(仿微信朋友圈拖动删除)

发朋友圈的时候,长按图片可以调整顺序,还可以拖动到底部删除。

Android开发教程拖动删除(仿微信朋友圈拖动删除)

2 官方示例:

https://developer.android.google.cn/guide/topics/ui/drag-drop.html

撸代码

1 首先布局布局画出来

一个RecyclerView+底部一个TextView




    

    


Android开发教程拖动删除(仿微信朋友圈拖动删除)

2 MainActivity 和 Adapter 的实现

这里简单不贴代码了。贴关键步骤吧

步骤1. 对要拖拽的View调用startDragAndDrop方法,

步骤2 对要监听拖放View的控件设置View.OnDragListener事件

好的根据上面的方法,撸代码

class SimpleAdapter: RecyclerView.Adapter() {

    companion object {
        var imgList= arrayListOf(SimpleBean(true,R.drawable.bag),SimpleBean(true,R.drawable.monkey))
    }

    var show=true

    fun changeShow(postion:Int,isShow:Boolean){
        try {
            imgList[postion].show=isShow
            notifyDataSetChanged()
        } catch (e: Exception) { //待改进
            e.printStackTrace()
        }
    }

    fun delete(postion:Int){
        imgList.removeAt(postion)
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): VH {
        return VH(LayoutInflater.from(parent?.context).inflate(R.layout.item_layout,parent,false))
    }

    override fun getItemCount(): Int {
    return imgList.size
    }

    override fun onBindViewHolder(holder: VH?, position: Int) {
        if(holder!=null){
            holder.itemView.item_img.setImageResource(imgList[position].img)
            holder.itemView.item_img.tag=position
            val data=ClipData.newPlainText("","") //ClipData 剪切板 存放数据 方便传输

            holder.itemView.setOnLongClickListener {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    it.startDragAndDrop(data,View.DragShadowBuilder(holder.itemView.item_img),it,View.DRAG_FLAG_OPAQUE) //步骤1
                }else{
  //View.DRAG_FLAG_OPAQUE 该属性 表示不使用半透明属性,可以点进源码查看,有对应好几种不同的Flag,可以使用自己想用的                  it.startDrag(data,View.DragShadowBuilder(holder.itemView.item_img),it,View.DRAG_FLAG_OPAQUE)//步骤1 
                }
            }

            if(imgList[position].show){
                holder.itemView.item_img.visibility=View.VISIBLE
            }else{
                holder.itemView.item_img.visibility=View.INVISIBLE
            }

        }

    }
    //这里可以实现自己的View.DragShadowBuilder 如果不用可以直接使用View.DragShadowBuilder默认的即可
    class MyDragShadowBuilder(view: View) : View.DragShadowBuilder(view) {


        lateinit var bitmapDrawable: Drawable

        init {
            bitmapDrawable = BitmapDrawable()
        }


        override fun onDrawShadow(canvas: Canvas?) {
            super.onDrawShadow(canvas)
            bitmapDrawable.draw(canvas)
        }

        override fun onProvideShadowMetrics(outShadowSize: Point?, outShadowTouchPoint: Point?) {
            super.onProvideShadowMetrics(outShadowSize, outShadowTouchPoint)
            view.isDrawingCacheEnabled = true
            bitmapDrawable = BitmapDrawable(view.drawingCache)
            bitmapDrawable.setBounds(0, 0, view.width, view.height)

            outShadowSize!!.set(view.width, view.height)
            outShadowTouchPoint!!.set(view.width / 2, view.height / 2)
        }
    }


    class VH(itemView:View): RecyclerView.ViewHolder(itemView)
}

上面代码,有2个方法,一个更新View显示和隐藏的方法,一个用于删除节点的方法

看看监听里面是怎么调用的呢

 delete.setOnDragListener { v, event ->
            println("v = [${v}], event = [${event}]")
            when(event.action){
                DragEvent.ACTION_DRAG_STARTED->{ //开始拖动
                 var imgView=event.localState as ImageView
                    delete.visibility= View.VISIBLE
                    delete.text="拖动到此处删除"
                    adapter.changeShow(imgView.tag.toString().toInt(),false)
                }
                DragEvent.ACTION_DRAG_EXITED->{ //拖动的View从TextView上移除
                    var imgView=event.localState as ImageView
                    delete.text="拖动到此处删除"
                    adapter.changeShow(imgView.tag.toString().toInt(),false)
                }
                DragEvent.ACTION_DRAG_ENTERED->{ // 拖动的View进入到的TextView上
                    delete.text="松手即可删除"
                    delete.setBackgroundColor(Color.parseColor("#D3504D"))
                    var imgView=event.localState as ImageView
                    adapter.changeShow(imgView.tag.toString().toInt(),false)
                }
                DragEvent.ACTION_DROP->{ // 在TextView上释放操作
                    Toast.makeText(this@MainActivity,"删除咯。。。",Toast.LENGTH_SHORT).show()
                    var imgView=event.localState as ImageView
                    adapter.delete(imgView.tag.toString().toInt())
                }
                DragEvent.ACTION_DRAG_ENDED->{//结束拖动事件
                    //var imgView=event.localState as ImageView
                    //adapter.changeShow(imgView.tag.toString().toInt(),true)
                }
            }
            true
        }

对了 用于控制对象的属性,所以我这里新建了一个实体类对应

data class SimpleBean(var show:Boolean, //控制View显示隐藏,在Adapter里可以看到对应的操作
                      var img:Int // 存放图片
                      )

好的最后看看效果,哈哈

Android开发教程拖动删除(仿微信朋友圈拖动删除)

注意事项

监听拖拽事件的View必须被设置为可见状态,不能被设置为Gone和Invisible,否则监不能被监听到拖拽事件,还没时间去看,是为什么原因,不过这里暂时可以处理成这样,默认设置为1x1像素大小的View,当监听到开始拖动的时候,还原到正常大小,哈哈,还没尝试,不过应该可以吧。