同屏EditText输入数据后RecyclerView停止视觉更新
RecyclerView stops visual updates after entering data in EditText on the same screen
在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) }
}
}
}
经过一些实验,我找到了一个解决方法:recycler.smoothScrollBy(1, 1)
在更改后成功更新回收器。仍然不知道这个问题的根本原因,希望这个解决方案对遇到这个问题的人有所帮助。
在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) }
}
}
}
经过一些实验,我找到了一个解决方法:recycler.smoothScrollBy(1, 1)
在更改后成功更新回收器。仍然不知道这个问题的根本原因,希望这个解决方案对遇到这个问题的人有所帮助。