Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnBindViewHolder does not apply after notifyitemmoved () in Android Recyclerview

The code above is the RecyclerViewAdapter, which changes color only when it is the first item, as shown below.

class TestAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private val textColor1 = Color.BLACK
private val textColor2 = Color.YELLOW
private val items = ArrayList<String>()

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val textColor = if(position==0) textColor1 else textColor2
    holder.itemView.textView.setTextColor(textColor)
    holder.itemView.textView.text = items[position]
}

fun move(from:Int,to:Int){
    val item = items[from]
    items.remove(item)
    items.add(to,item)
    notifyItemMoved(from,to)
}
}

enter image description here

In this state I would like to move Value 3 to the first position using the move function. The results I want are shown below.

enter image description here

But in fact, it shows the following results

enter image description here

When using notifyDataSetChanged, I can not see the animation transition effect,

Running the onBindViewHolder manually using findViewHolderForAdapterPosition results in what I wanted, but it is very unstable. (Causing other parts of the error that I did not fix)

fun move(from:Int,to:Int){
    val item = items[from]
    val originTopHolder = recyclerView.findViewHolderForAdapterPosition(0)
    val afterTopHolder = recyclerView.findViewHolderForAdapterPosition(from)
    items.remove(item)
    items.add(to,item)
    notifyItemMoved(from,to)
    if(to==0){
        onBindViewHolder(originTopHolder,1)
        onBindViewHolder(afterTopHolder,0)
    }
}

Is there any other way to solve this?

like image 764
H.Kim Avatar asked Dec 18 '22 21:12

H.Kim


2 Answers

Using the various notifyItemFoo() methods, like moved/inserted/removed, doesn't re-bind views. This is by design. You could call

if (from == 0 || to == 0) {
    notifyItemChanged(from, Boolean.FALSE);
    notifyItemChanged(to, Boolean.FALSE);
}

in order to re-bind the views that moved.

like image 174
Ben P. Avatar answered May 12 '23 05:05

Ben P.


notifyItemMoved will not update it. According to documentation:

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter

This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered.

What you're seeing is expected.

Might want to look into using notifyItemChanged, or dig through the documentation and see what works best for you.

like image 44
sbso Avatar answered May 12 '23 06:05

sbso