Android Recyclerview Remove Animation Is Applied To All Items Strange Behaviour

Viewed 1449

I am using following library to animate items in my recyclerview on removal https://github.com/wasabeef/recyclerview-animators

I am trying to apply slide to right animation to only removed item but for some reason all items in recyclerview disappears first and then animated back to their position strangely. Please watch the following video. enter image description here

Here is my code its very simple:

   friends_screen_friendlist_recyclerview.itemAnimator = SlideInRightAnimator()
                   friends_screen_friendlist_recyclerview.itemAnimator?.apply {
                        addDuration = 120;
                       removeDuration = 1000;
                        moveDuration = 500;
                        changeDuration = 500;
                   }
    friendItems.removeAt(0)

               friends_screen_friendlist_recyclerview.adapter!!.notifyItemRemoved(0)

Adapter class:

class FriendListAdapter(val items : ArrayList<FriendListItem>, val context: Context,val listener:FriendListListener) : androidx.recyclerview.widget.RecyclerView.Adapter<FriendListViewHolder>(),Filterable {

    var filterItems = ArrayList<FriendListItem>()

    init{
        filterItems = items
    }
    // Gets the number of animals in the list
    override fun getItemCount(): Int {
        return filterItems.size
    }
    override fun getItemViewType(position: Int): Int {
        return position
    }

    override fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val charSearch = constraint.toString()
                if (charSearch.isEmpty()) {
                    filterItems = items
                } else {
                    val resultList = ArrayList<FriendListItem>()
                    for (row in items) {
                        if (row.userName.toLowerCase(Locale.ROOT).contains(charSearch.toLowerCase(Locale.ROOT))) {
                            resultList.add(row)
                        }
                    }
                    filterItems = resultList
                }
                val filterResults = FilterResults()
                filterResults.values = filterItems
                return filterResults
            }

            @Suppress("UNCHECKED_CAST")
            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                filterItems = results?.values as ArrayList<FriendListItem>
                notifyDataSetChanged()
            }

        }
    }

    // Inflates the item views
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FriendListViewHolder {
        return FriendListViewHolder(LayoutInflater.from(context).inflate(R.layout.friendlist_item, parent, false))
    }

    // Binds each animal in the ArrayList to a view
    override fun onBindViewHolder(holder: FriendListViewHolder, position: Int) {
        //holder?.profileImage?.background = items[position].profileImage
        holder?.userName?.text = filterItems[position].userName
        holder?.level?.text = "Seviye "+filterItems[position].level

        // do the necessary profilePic checks.
        Picasso.get().load(filterItems[position].profileImage).into(holder?.profileImage, object : Callback {
            override fun onSuccess() {
                listener.onProfilePicLoaded()
            }

            override fun onError(e: Exception?) {
                listener.onProfilePicLoaded() // error but anyway. just tell messages class its loaded so it can show the page.

            }
        })


  if(filterItems[position].gender == 0){
            holder?.gender?.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.male_icon))
        }else{
            holder?.gender?.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.female_icon))

        }

        if(filterItems[position].isOnline){
            holder?.isOnline?.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.online_circle))
        }else{
            holder?.isOnline?.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.offline_circle))

        }


        holder.itemContainer.setOnClickListener {
            listener.onFriendSelected(filterItems[position])


        }
        holder.itemContainer.setOnLongClickListener {
            listener.onFriendSelectedAndHolded(filterItems[position],position)
            Log.d("yunusdebug","long")


            return@setOnLongClickListener true

        }


    }


}

class FriendListViewHolder (view: View) : androidx.recyclerview.widget.RecyclerView.ViewHolder(view) {
    // Holds the TextView that will add each animal to
    val itemContainer = view.friendlist_item_container

    val userName = view.friendlist_item_username_textview

    val level = view.friendlist_item_level_textview
    val isOnline = view.friendlist_item_isOnline
    val profileImage = view.friendlist_item_profile_image
    val gender = view.friendlist_item_gender

}
1 Answers

When you remove an item in your adapter you should also notify the new range. Please try the following:

friendItems.removeAt(index)
notifyItemRemoved(index)
notifyItemRangeChanged(index,friendItems.size)
Related