编辑列表视图上的列表项

问题描述 投票:0回答:1

想象一下,我们有一个简单的项目清单。每个项目仅包含一个简短的标题。为了处理列表,我们将RecyclerView与ListAdapter和ViewHolders一起使用。除非我们单击,否则每个项目/视图均不可编辑。

在这种情况下,我将一个视图模型用于列表,将一个视图模型用于正在编辑的项目。不幸的是,我所有的尝试都失败了。

我尝试使用两个不同的视图持有人,但是在所有夸大视图(在这种情况下为绑定)之后,列表一直闪烁。我给的另一个镜头是使用相同的视图持有者,但有两种不同的绑定方法-一个绑定普通项目,第二个绑定使用viewmodel而不是数据对象绑定,但同样失败-突然有几行是可编辑的。

有人解决了吗?

    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
    }
}
android android-recyclerview recycler-adapter android-viewmodel
1个回答
0
投票

通过改变我对问题的解决方法,我解决了它。我将所有列表项都设为可编辑状态,但同时我也关注了焦点。长话短说,我在我的editTexts上借助OnFocusChangeListener和TextWatcher调用项视图模型方法。

© www.soinside.com 2019 - 2024. All rights reserved.