发朋友圈的时候,长按图片可以调整顺序,还可以拖动到底部删除。
https://developer.android.google.cn/guide/topics/ui/drag-drop.html
一个RecyclerView+底部一个TextView
"1.0" encoding="utf-8"?>
.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:layout_editor_absoluteY="81dp">
.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="@+id/delete"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints"> .support.v7.widget.RecyclerView>
"@+id/delete"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="#E85653"
android:gravity="center"
android:text="拖动到此处删除"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/recyclerView"
tools:ignore="MissingConstraints" />
.support.constraint.ConstraintLayout>
这里简单不贴代码了。贴关键步骤吧
步骤1. 对要拖拽的View调用startDragAndDrop方法,
步骤2 对要监听拖放View的控件设置View.OnDragListener事件
好的根据上面的方法,撸代码
class SimpleAdapter: RecyclerView.Adapter.VH>() {
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 // 存放图片
)
好的最后看看效果,哈哈
监听拖拽事件的View必须被设置为可见状态,不能被设置为Gone和Invisible,否则监不能被监听到拖拽事件,还没时间去看,是为什么原因,不过这里暂时可以处理成这样,默认设置为1x1像素大小的View,当监听到开始拖动的时候,还原到正常大小,哈哈,还没尝试,不过应该可以吧。
好久没写了, 最近好忙,都没时间去仔细写,好像也没有写过很详细的,哈哈, 这样感觉还是不对的。
慢慢养成一个好习惯,在忙也坚持坚持 ,也不知道有没有人看,就当自己留个记录以后万一有用得着的地方呢,下一篇想写
源码就不传了,贴贴就用能。
晚安
2018年4月15日23:05:07