mikepenz/FastAdapter

Custom drag view

morand1 opened this issue · 6 comments

About this issue

  • Missing IExtendedDraggable documentation

Details

  •  Used library version
  •  Used support library version
  •  Used gradle build tools version
  •  Used tooling / Android Studio version
  •  Other used libraries, potential conflicting libraries

Checklist

Is there a sample for IExtendedDraggable? I'm trying to use it with AbstractBindingItem but it is not working properly.

This is how my Item looks like:

class MyItem(
    val model: model,
    myTouchHelper: ItemTouchHelper
) : AbstractBindingItem<MyItemBinding>(), IExtendedDraggable<BindingViewHolder<MyItemBinding>> {

    override val type: Int
        get() = R.id.type

    private var binding: MyItemBinding? = null

    override fun bindView(binding: MyItemBinding, payloads: List<Any>) {
        this.binding = binding
        binding.apply {
            title.text = model.name
            checkbox.isChecked = model.checked
        }
    }

    override val isDraggable: Boolean
        get() = true
    
    override val touchHelper: ItemTouchHelper = myTouchHelper

    override fun getDragView(viewHolder: BindingViewHolder<MyItemBinding>): View? =
        binding?.dragIcon

    override fun createBinding(inflater: LayoutInflater, parent: ViewGroup?): MyItemBinding {
        return MyItemBinding.inflate(inflater, parent, false)
    }

and creating adapter:

       val itemAdapter: ItemAdapter<Item> = items()
       val fastAdapter = FastAdapter.with(itemAdapter)

      binding?.recyclerView?.apply {
            adapter = fastAdapter
            layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
        }

        val touchCallback = SimpleDragCallback(object : ItemTouchCallback {
            override fun itemTouchOnMove(oldPosition: Int, newPosition: Int): Boolean {
                DragDropUtil.onMove(itemAdapter, oldPosition, newPosition)  // change position
                return true
            }
        })
        val touchHelper = ItemTouchHelper(touchCallback)
        val list = listOf(
            Item(Model("1", false), touchHelper),
            Item(Model("2", false), touchHelper),
            Item(Model("3", false), touchHelper)
        )

        itemAdapter.add(list)

What am I missing?

@morand1 the sample app sadly does not contain a sample code. this is extension functionality contributed by @MFlisar as part of: https://github.com/mikepenz/FastAdapter/blob/3aadf2fbb037883b3dc6532cb79fae2c4736e85c/library-extensions-utils/src/main/java/com/mikepenz/fastadapter/utils/DragDropUtil.kt

(introduced pre v2.x)

Those extensions are provided as-is and are only meant as small utils to perhaps help with special usecases.

What specific usecase are you trying to achieve? Maybe there's better alternative support provided by google since.

I need to achieve the same behavior as described here: #914 My item has icon which should be responsible for dragging, not the whole item.

I see @manray2210 achieved the required usecase. @manray2210 would you please so kind to highlight your solution please? Or maybe you'd love to contribute a sample usecase to highlight its implementation?

This util is very old already but I still use it inside one of my current apps - what I see quickly, is that you have not called the second function in the utility class, the Item needs to set the TouchListener to the drag icon like, in my app I do it like following:

 override fun bindView(holder: ViewHolder, payloads: List<Any>) {
    super.bindView(holder, payloads)

    itemTouchHelper?.let {
        DragDropUtil.bindDragHandle(holder, this as IExtendedDraggable<RecyclerView.ViewHolder>)
    }
    holder.dragHandle?.visibility = if (draggable) View.VISIBLE else View.GONE

    // ...
}

Should I use also DragDropUtil.onMove(itemAdapter, oldPosition, newPosition) in SimpleDragCallback ?
@MFlisar you mentioned also here: #229 to "disable the drag enabled". So should it be something like this:

val touchCallback = SimpleDragCallback(object : ItemTouchCallback {
            override fun itemTouchOnMove(oldPosition: Int, newPosition: Int): Boolean {
                DragDropUtil.onMove(itemAdapter, oldPosition, newPosition) 
                return true
            }
        })

        touchCallback.isDragEnabled = false
        val touchHelper = ItemTouchHelper(touchCallback)
        val list = listOf(
            Item(Model("1", false), touchHelper),
            Item(Model("2", false), touchHelper),
            Item(Model("3", false), touchHelper)
        )
        touchHelper.attachToRecyclerView(binding?.recyclerView)

        itemAdapter.add(list)

After adding this DragDropUtil.bindDragHandle I'm getting java.lang.IndexOutOfBoundsException: Index: -1, Size: 2 from this SimpleDragCallback.

Ok I checked it with AbstractItem and it works properly. The problem is with AbstractBindingItem.