Редактирование элемента списка в представлении списка - PullRequest
0 голосов
/ 07 января 2020

Представьте, что у нас есть простой список предметов. Каждый элемент содержит только краткое название. Для обработки списка мы используем RecyclerView с ListAdapter и ViewHolders. Каждый элемент / представление нельзя редактировать, если мы не щелкнем по нему.

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

Я пытался использовать два разных держателя вида, но список мерцал, после того как все надувающие представления (в данном случае привязка) тяжелые. Еще один снимок, который я дал, чтобы использовать один и тот же держатель представления, но с двумя различными методами связывания - одним связывающим простым элементом, вторым - связыванием с моделью представления вместо объекта данных, но это также не удалось - внезапно несколько строк стали редактируемыми.

Кто-нибудь решил это?

    class MistakesAdapter(private val editViewModel: MistakeEditViewModel) :
    ListAdapter<Mistake, RecyclerView.ViewHolder>(MistakesDiffCallback()) {

    companion object{
        const val ITEM_PLAIN_VIEW_TYPE = 0
        const val ITEM_EDITABLE_VIEW_TYPE = 1
    }

    private var itemPositionUnderEdit = -1

    private val listener = object: MistakeItemListener{
        override fun onClick(view: View, position: Int) {
            Timber.d("OnClick : edit - $itemPositionUnderEdit, clickPos - $position")
            editViewModel.onEditMistake(getItem(position))
            itemPositionUnderEdit = position
            notifyItemChanged(itemPositionUnderEdit)
        }
    }

    override fun getItemViewType(position: Int) =
        when (position) {
            itemPositionUnderEdit -> ITEM_EDITABLE_VIEW_TYPE
            else -> ITEM_PLAIN_VIEW_TYPE
        }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
        when (viewType) {
            ITEM_EDITABLE_VIEW_TYPE -> EditableMistakeViewHolder.from(parent)
            else -> MistakeViewHolder.from(parent)
        }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is EditableMistakeViewHolder -> holder.bind(editViewModel, listener)
            is MistakeViewHolder -> holder.bind(getItem(position), listener)
            else -> throw ClassCastException("Unknown view holder type")
        }
    }

    class MistakeViewHolder private constructor(private val binding: ListItemMistakesBinding) :
        RecyclerView.ViewHolder(binding.root) {

        companion object {
            fun from(viewGroup: ViewGroup): MistakeViewHolder {
                val inflater = LayoutInflater.from(viewGroup.context)
                val binding = ListItemMistakesBinding.inflate(inflater, viewGroup, false)
                return MistakeViewHolder(binding)
            }
        }

        fun bind(item: Mistake, listener: MistakeItemListener) {
            binding.apply {
                mistake = item
                inputType = InputType.TYPE_NULL
                this.listener = listener
                position = adapterPosition
                executePendingBindings()
            }
        }
    }

    class EditableMistakeViewHolder private constructor(private val binding: ListItemMistakesBinding)
        : RecyclerView.ViewHolder(binding.root) {

        companion object{
            fun from(viewGroup: ViewGroup): EditableMistakeViewHolder {
                val inflater = LayoutInflater.from(viewGroup.context)
                val binding = ListItemMistakesBinding.inflate(inflater, viewGroup, false)
                return EditableMistakeViewHolder(binding)
            }
        }

        fun bind(viewModel: MistakeEditViewModel, listener: MistakeItemListener){
            binding.apply {
                this.viewModel = viewModel
                inputType = InputType.TYPE_CLASS_TEXT
                this.listener = listener
                position = adapterPosition
                root.setBackgroundColor(Color.GRAY)
            }
        }
    }
}




class MistakeEditViewModel(private val repository: MistakesRepository) : ViewModel() {

 @VisibleForTesting
    var mistakeUnderEdit: Mistake? = null

    //two-way binding
    val mistakeName = MutableLiveData<String>()

    fun onEditMistake(mistake: Mistake) {
        mistakeUnderEdit = mistake
        mistakeName.value = mistake.name
    }
}

1 Ответ

0 голосов
/ 07 января 2020

Изменяя свой подход к проблеме, я решил ее. Я делаю все элементы списка редактируемыми, но в то же время я следую за фокусом. Короче говоря, я вызываю методы модели представления элементов с помощью OnFocusChangeListener и TextWatcher в моих editTexts.

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