Поведение RecyclerView: конкретная настройка строки дублируется в другой строке (Kotlin) - PullRequest
0 голосов
/ 05 июля 2018

Я новичок в Android dev и теперь портирую свое приложение для iOS. Попытка сделать довольно сложный RecyclerView, но в какой-то момент поведение определенной строки дублируется в другой строке после метода notifyDataSetChanged ().

В первой части RecyclerView есть три строки с одинаковым ViewType

Каждый из них имеет виджеты 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 голосов
/ 05 июля 2018

Этот тип проблемы с RecyclerView, когда один элемент таинственным образом принимает атрибуты или поведение другого элемента, как правило, происходит из-за отсутствия сброса держателя вида.

Вы определяете поведение держателей ваших представлений при их создании, поэтому в первый раз все держатели представлений создаются и ведут себя соответствующим образом. Когда все меняется, держатели просмотра повторно используются и не воссоздаются. В результате все может смешаться, например, когда открывается диалоговое окно, когда должна появиться клавиатура.

Чтобы исправить это, сбросьте держатель вида, когда он будет вести себя так, как вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...