EdgeDev
EdgeDev

Reputation: 2486

How to get ViewHolder Recycler ViewHolder Index

Recycler View dynamically generate view holders to fill the screen (plus some extras) then it recycles the generated view holders.

As you'll see in the code below, i intend to customize an Index View of the Recycler View. Since the viewHolder is recycled, if i customize the viewHolder based on the index, it will be repeated for other indexes.

//... other RecyclerViewAdapter Code
override fun onBindViewHolder(holder: StringViewHolder, position: Int) {
    holder.string_txt_view.text = stringList[position]
    holder.index_txt_view.text = DecimalFormat("#,###.##").format(position + 1)
    if (selectedIndex.contains(position)) {
        holder.string_txt_view.setTextColor(Color.WHITE)
        holder.index_txt_view.setTextColor(Color.WHITE)
        holder.rootView.setBackgroundColor(Color.BLACK)
        holder.string_txt_view.setTextSize(20f)
    } else {
        holder.string_txt_view.setTextColor(Color.BLACK)
        holder.string_txt_view.setTextSize(16f)
        holder.index_txt_view.setTextColor(Color.BLACK)
        holder.rootView.setBackgroundColor(Color.TRANSPARENT)
    }
}

In order to prevent this, i have to use if-else in the bind view holder. The else statement, resets the views to the default config if does it does not meet the condition.

I have performance concerns, because i am manually setting everything (that was already default) instead of being specific.

How can i get the index of the viewHolder so that my actions can be targeted.

Upvotes: 0

Views: 336

Answers (1)

gi097
gi097

Reputation: 7703

The if (selectedIndex.contains(position)) { is probably causing the performance issues you are facing since it's O(n) and it's being called everytime a row becomes visible. Instead of using contains, you can initialize a boolean array like this (which is still an ugly approach, but it should be faster) since it's O(1):

boolean[] selectedIndex = new boolean[stringList.length];

// If selected set to true
selectedIndex[position] = true;

if (selectedIndex[position]) {
   // It's selected 
}

You can also add a isSelected boolean to the stringList elements instead instead of always querying the selectedIndex which is much better.

Upvotes: 1

Related Questions