【问题标题】:ViewHolder click is messing other viewsViewHolder 点击正在弄乱其他视图
【发布时间】:2018-06-13 15:38:19
【问题描述】:

我有以下 RecyclerView.Adapter

class SpeciesAdapter(val activity: Activity, private val species: ArrayList<Specie>) : RecyclerView.Adapter<SpeciesAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return ViewHolder(inflater.inflate(R.layout.specie_item, parent, false))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val specie = species[position]
        holder.specie.text = specie.name
        holder.header.setOnClickListener {
            if (holder.information.visibility == View.GONE) showInformation(holder)
            else hideInformation(holder)
        }
    }

    private fun showInformation(holder: ViewHolder) {
        holder.information.visibility = View.VISIBLE
        holder.arrow.rotation = -90f
    }

    private fun hideInformation(holder: ViewHolder) {
        holder.information.visibility = View.GONE
        holder.arrow.rotation = 90f
    }

    override fun getItemCount() = species.size

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val header: RelativeLayout = view.header_layout
        val arrow: ImageView = view.arrow_image
        val specie: TextView = view.specie_text
        val information: LinearLayout = view.information_layout
    }
}

并且正在制作这个:

https://media.giphy.com/media/9JcLhfgXOdt81WUxsE/giphy.mp4

如您所见,如果我单击一个项目,则会打开一个带有加载的布局。我的问题是,当我单击一个项目然后滚动时,也会打开其他一些项目,但我没有单击它们。就像 ViewHolder 正在回收视图,并不关心带有加载栏的布局是否不可见。

我的适配器可能有什么问题?

【问题讨论】:

标签: android scroll android-recyclerview kotlin android-viewholder


【解决方案1】:

好吧,你要明白的是,ViewHolder 是一个可以在给定时间代表任何 Specie 对象的视图。这个 ViewHolder 被 RecyclerView 重用,并在有一些滚动时绑定到其他 Specie 对象,试图加载最少数量的 View(这就是它被称为“Recycler”的原因)。

如果您只是更改一个 Specie 项目的持有人的属性,当该持有人被重复使用以显示另一个 Specie 对象时,如果您不“重置”它,该属性将保持不变。

简而言之,您必须在 bind 方法中设置所有 ViewHolder 属性,以确保持有者现在正确地表示将要显示的 Specie 对象。

也就是说,你必须做的,例如,保持一个列表或映射,或者你想知道什么 Specie 对象在给定时间被“扩展”了,当调用 bind 方法时,检查是否该特定的 Specie 对象必须扩展或不扩展,并根据它显示持有者扩展信息。


编辑问题解决方案:

class SpeciesAdapter(val activity: Activity, private val species: ArrayList<Specie>) : RecyclerView.Adapter<SpeciesAdapter.ViewHolder>() {

    // added an ArrayList to store the opened species
    private val opened = arrayListOf<Specie>()

    // ...

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val specie = species[position]

        // added a condition to check if a specie was opened
        // and updates according to the result
        if (opened.contains(specie)) showInformation(holder, specie)
        else hideInformation(holder, specie)

        holder.specie.text = specie.name
        holder.header.setOnClickListener {
            if (holder.information.visibility == View.GONE) showInformation(holder, specie)
            else hideInformation(holder, specie)
        }
    }

    private fun showInformation(holder: ViewHolder, specie: Specie) {
        holder.information.visibility = View.VISIBLE
        holder.arrow.rotation = -90f

        // checking if is opened to avoid duplicates
        if (!opened.contains(specie)) opened.add(specie)
    }

    private fun hideInformation(holder: ViewHolder, specie: Specie) {
        holder.information.visibility = View.GONE
        holder.arrow.rotation = 90f

        // checking if exists to avoid crashes
        if (opened.contains(specie)) opened.remove(specie)
    }

    // ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 2021-01-07
    • 2019-12-01
    • 2016-05-13
    • 2015-04-12
    • 2013-09-07
    • 1970-01-01
    相关资源
    最近更新 更多