【问题标题】:RecyclerView stops visual updates after entering data in EditText on the same screenRecyclerView 在同一屏幕上的 EditText 中输入数据后停止视觉更新
【发布时间】:2020-04-15 13:21:10
【问题描述】:

在 Fragment 中,有 EditText 执行搜索和 RecyclerView 显示结果。使用数据初始填充 RecyclerView 工作正常,但在您输入数据并显示软键盘时与 EditText 首次交互后,RecyclerView 停止视觉更新数据。
notifyDataSetChanged() notifyItemRangeRemoved() 适配器方法不会在视觉上更新 RecyclerView,并且 DiffUtil 的使用没有解决问题。适配器接收到新数据,但视觉上 RecyclerView 没有更新除非您手动滚动它。
你有什么想法或线索为什么会发生?任何帮助表示赞赏。

布局代码:

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">

    <FrameLayout
        android:id="@+id/fl_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        android:padding="@dimen/10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <EditText
            android:id="@+id/et_search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </FrameLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_results"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:clipToPadding="false"
        android:orientation="vertical"
        android:overScrollMode="never"
        android:padding="@dimen/default_padding"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/fl_search" />

</androidx.constraintlayout.widget.ConstraintLayout>

片段代码:

...
        adapter = MyRecyclerViewAdapter( object : MyRVClickListener {
                override fun onItemClicked(
                    position: Int,
                    myDAO: MyDAO
                ) {
                  //  My click action                    
                }
            }
        )

        resultListRV = view.rv_results
        layoutManager =
            LinearLayoutManager(activity!!)

        resultListRV?.layoutManager = layoutManager!!

        val divider = DividerItemDecoration(
            resultListRV?.context,
            DividerItemDecoration.VERTICAL
        )

        divider.setDrawable(
            ContextCompat.getDrawable(appContext, R.drawable.divider_hor)!!
        )

        resultListRV?.addItemDecoration(divider)
        resultListRV?.adapter = adapter

        myViewModel.dataList.observe(viewLifecycleOwner, Observer {
            adapter.submitList(it)
        })
...

适配器代码:

class MyRecyclerViewAdapter(
    val listener: MyRVClickListener
) : ListAdapter<MyDAO, RecyclerView.ViewHolder>(DiffCallback) {

    companion object DiffCallback : DiffUtil.ItemCallback<MyDAO>() {
        override fun areItemsTheSame(
            oldItem: MyDAO,
            newItem: MyDAO
        ): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(
            oldItem: MyDAO,
            newItem: MyDAO
        ): Boolean {
            return oldItem.id== newItem.id
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val item = getItem(position)
        (holder as SearchItemVH).bind(item, position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return SearchItemVH(
            LayoutInflater.from(parent.context).inflate(
                R.layout.search_list_item,
                parent,
                false
            )
        )
    }

    inner class SearchItemVH(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var title: TextView = itemView.list_item_tv_title

        fun bind(listItem: MyDAO, position: Int) {
            title.text = listItem.details.description
            itemView.setOnClickListener { listener.onItemClicked(position, listItem) }
        }
    }
}

【问题讨论】:

  • 也添加代码
  • "除非您手动滚动",请尝试在notifyDataSetChanged 之前以编程方式将焦点移至 RecyclerView ..
  • @Black4Guy 添加了代码。不幸的是简单的请求焦点方法调用没有任何效果
  • 更新/更改数据的代码在哪里?你在哪里调用 notifyDataSetChanged?
  • @JensV 我在这个例子中使用 Diff Util 所以更新/更改数据在这里 myViewModel.dataList.observe(viewLifecycleOwner, Observer { adapter.submitList(it) }) 如果我在那里添加 notifyDataSetChanged 它什么都不会改变而且它工作得很好,直到我开始在 EditText 中输入数据

标签: android kotlin android-recyclerview androidx


【解决方案1】:

经过一些实验,我找到了一种解决方法:recycler.smoothScrollBy(1, 1)在更改后成功更新回收器。仍然不知道这个问题的原始原因,如果有人遇到这个问题,希望这个解决方案会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多