【发布时间】:2021-10-13 00:35:16
【问题描述】:
我在 recyclerview 中添加了一个动画来显示下面的过渡。
当我长按一个项目时,它会显示单选按钮并且项目卡会向右移动。问题是,在初始选择后,当我单击或选择其他项目时,item6 和下面的项目再次动画。
谁能解释为什么会发生这种情况以及我该如何解决这个问题。
ListAdapter.kt:
class ListItemAdapter(private val values: List<PlaceholderContent.PlaceholderItem>
) : RecyclerView.Adapter<ListItemAdapter.ItemViewHolder>() {
private lateinit var itemClick: OnItemClick
private var selectedIndex: Int = -1
private var selectedItems: SparseBooleanArray = SparseBooleanArray()
private var isActive: Boolean = false
private var activateAnimation: Boolean = false
fun setItemClick(itemClick: OnItemClick) {
this.itemClick = itemClick
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ListItemAdapter.ItemViewHolder {
val view = LayoutInflater.from(parent.context).inflate(
R.layout.fragment_item,
parent,
false
)
return ItemViewHolder(view)
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
holder.itemView.apply {
findViewById<TextView>(R.id.item_number).text = values[position].id
findViewById<TextView>(R.id.content).text = values[position].content
}
holder.itemView.findViewById<CardView>(R.id.list_item).setOnClickListener {
itemClick.onItemClick(values[position], position)
}
holder.itemView.findViewById<CardView>(R.id.list_item).setOnLongClickListener {
itemClick.onLongPress(values[position], position)
true
}
toggleIcon(holder, position)
}
override fun getItemCount(): Int {
return values.size
}
private fun itemTransition(holder: ItemViewHolder){
val animator = ObjectAnimator.ofFloat(holder.itemView.findViewById(R.id.list_item), View.TRANSLATION_X, 150f)
animator.start()
}
private fun itemTransitionBack(holder: ItemViewHolder){
val animator = ObjectAnimator.ofFloat(holder.itemView.findViewById(R.id.list_item), View.TRANSLATION_X, 0f)
animator.start()
}
fun toggleIcon(holder: ItemViewHolder, position: Int){
val checkBox = holder.itemView.findViewById<RadioButton>(R.id.is_selected)
if(selectedItems.get(position, false)){
checkBox.isGone = false
checkBox.isChecked = true
}
else{
checkBox.isGone = true
checkBox.isChecked = false
}
if(isActive) checkBox.isGone = false
if(activateAnimation){
itemTransition(holder)
}
else
itemTransitionBack(holder)
if(selectedIndex == position) selectedIndex = - 1
}
fun selectedItemCount() = selectedItems.size()
fun toggleSelection(position: Int){
selectedIndex = position
if (selectedItems.get(position, false)){
selectedItems.delete(position)
}else {
selectedItems.put(position, true)
}
notifyItemChanged(position)
isActive = selectedItems.isNotEmpty()
activateAnimation = selectedItems.isNotEmpty()
notifyDataSetChanged()
}
fun clearSelection(){
selectedItems.clear()
notifyDataSetChanged()
}
interface OnItemClick {
fun onItemClick(item: PlaceholderContent.PlaceholderItem, position: Int)
fun onLongPress(item: PlaceholderContent.PlaceholderItem, position: Int)
}
inner class ItemViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
}
}
ItemFragment.kt
adapter = ListItemAdapter(PlaceholderContent.ITEMS)
val recyclerViewList = view.findViewById<RecyclerView>(R.id.list)
recyclerViewList.adapter = adapter
recyclerViewList.layoutManager = LinearLayoutManager(view.context, LinearLayoutManager.VERTICAL, false)
val myHelper = ItemTouchHelper(myCallback)
myHelper.attachToRecyclerView(recyclerViewList)
adapter.setItemClick(object : ListItemAdapter.OnItemClick{
override fun onItemClick(
item: PlaceholderContent.PlaceholderItem,
position: Int
) {
if(adapter.selectedItemCount() > 0)
toggleSelection(position)
}
override fun onLongPress(
item: PlaceholderContent.PlaceholderItem,
position: Int
) {
toggleSelection(position)
}
})
private fun toggleSelection(position: Int){
adapter.toggleSelection(position)
}
【问题讨论】:
-
您能解释一下为什么在
toggleSelection(position: Int)方法中同时使用notifyItemChanged和notifyDataSetChanged吗?他们每次都在调用更新单个项目的状态。你检查过删除那部分吗?告诉我 -
使用 notifyDataSetChanged() 的原因是通知所有项目它们应该显示复选框以供选择。然后在整个 recyclerview 项目中所有复选框都可见并且用户按下随机项目之后。我需要通知该项目以显示复选框已选中,为此我使用 notifyItemChanged。
-
但这两个语句强制每个项目都更新,但您的视图持有者当前正常持有 5 个项目,您应该只更新正在更新其视图的项目位置。调用 notifyDataSetChanged 成为此解决方案的昂贵语句。如果你在 GitHub 上有这个项目,请分享 GitHub 公开链接,以便我正确查看。
标签: android kotlin android-recyclerview android-animation