【发布时间】: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