You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Telegram安卓端RecyclerView长按多选的复选框入场动画效果

问题描述

我正尝试在RecyclerView中实现动画效果,目标效果与Telegram安卓应用中的动画一致。
在Telegram中打开聊天界面后长按消息,RecyclerView会进入多选模式并展示复选框,我想要复现完全相同的交互效果。

当前实现效果:
当前实现效果图

相关代码

ListItemAdapter.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

    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: ListItemAdapter.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.setOnClickListener {
            itemClick.onItemClick(values[position], position)
        }

        holder.itemView.setOnLongClickListener {
            itemClick.onLongPress(values[position], position)
            true
        }
        toggleIcon(holder, position)
    }

    override fun getItemCount(): Int {
        return values.size
    }



    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(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()
        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){
    }

}

fragment_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:id="@+id/list_item"
    >
    <RadioButton
        android:id="@+id/is_selected"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_margin="16dp"
        />

    <TextView
        android:id="@+id/item_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/text_margin"
        android:textAppearance="?attr/textAppearanceListItem" />

    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/text_margin"
        android:textAppearance="?attr/textAppearanceListItem" />


</LinearLayout>

MainActivity.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)
    }

})


return view
}

private fun toggleSelection(position: Int){
    adapter.toggleSelection(position)
}

内容的提问来源于stack exchange,提问作者pepperlove

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 23:18:03