RecyclerView行为:特定行的自定义在其他行上重复(科特琳)

时间:2018-07-05 14:06:39

标签: android android-recyclerview kotlin

我是Android开发人员中的新手,现在正在移植我的iOS应用程序。 试图使RecyclerView变得非常复杂,但是有时在notifyDataSetChanged()方法之后,特定行的行为会在另一行上重复。

There are three rows with same ViewType in first part of RecyclerView

它们每个都有TextView和EditText小部件,我在CustomViewHolder类中进行填充。
第一行和第二行应该像往常一样工作:当我单击EditText时,键盘将打开。但是第三行EditText的焦点应该启动对话框警报。在重新加载适配器的DataSet之前,一切工作正常。重新加载DataSet之后,第一行的EditText也开始打开对话框警报,而不是正常打开键盘。

自定义行时,看起来好像缺少了某些东西,并以某种方式引用了同一对象。这是我的适配器代码(简体):

class NewRequestsRecyclerAdapter(val context: Context, val parameters:ArrayList<NewRequestsFragment.ParameterCell>,val delegate:NewRequestProtocol?): RecyclerView.Adapter<NewRequestsRecyclerAdapter.CustomViewHolder>() {

enum class RowType {
    Header,Parameter
}

override fun getItemCount(): Int {
    // count logic
}

override fun onCreateViewHolder(parent : ViewGroup, viewType: Int): CustomViewHolder {
    val layoutInflater = LayoutInflater.from(parent.context)
    val cellForRow = when (RowType.values()[viewType]) {
        RowType.Header -> layoutInflater.inflate(R.layout.cell_header,parent,false)
        RowType.Parameter -> layoutInflater.inflate(R.layout.cell_parameter_new_requests,parent,false)
     }

    return CustomViewHolder(cellForRow, RowType.values()[viewType])
}

override fun getItemViewType(position: Int): Int {
    // Here's ItemViewType logic ...
}

override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
    holder.bindMenu(position)
}

inner class CustomViewHolder(val cellView: View, val type:RowType): RecyclerView.ViewHolder(cellView) {
    fun bindMenu(row:Int) {

        when (type) {
            RowType.Header -> {
                val nameView = cellView.findViewById<TextView>(R.id.headerName)
                // other logic to populate Header views
            }
            RowType.Parameter -> {
                val nameView = cellView.findViewById<TextView>(R.id.paramName)
                val editText = cellView.findViewById<EditText(R.id.paramEditText)
                nameView.text = parameters[row-1].name
                editText.apply {
                    hint = parameters[row-1].placeholder
                    when (parameters[row-1].type) {
                        NewRequestsFragment.PartsCellType.Name -> {
                            setText(delegate?.currentItem?.name)
                        }
                        NewRequestsFragment.PartsCellType.Number -> {
                            setText(delegate?.currentItem?.number)
                        }
                        NewRequestsFragment.PartsCellType.StateType-> {
                            setText(delegate?.currentItem?.state)
                            showSoftInputOnFocus = false
                            setOnFocusChangeListener { view, changed ->
                                if (changed) {
                                    inputType = InputType.TYPE_NULL
                                    delegate?.showStateDialog()
                                }
                            }
                        }
                    }
                }
            }

我知道可以解决此问题,我可以通过按钮显示警报,但是我想知道为什么我的代码会导致这种情况。
你能指导我我所缺少的吗?

1 个答案:

答案 0 :(得分:0)

RecyclerView这类问题,其中一个项目神秘地具有另一项目的属性或行为,通常是由于未重置视图所有者。

您正在定义视图持有者在创建时的行为,因此,第一次创建所有视图持有者并使其行为适当。当事情发生变化时,视图所有者将被重用,而不是重新创建。结果,事情可能会变得混乱,例如在键盘应该显示时打开对话框。

要更正此问题,请在绑定视图支架时使其重置为您想要的方式。