RecyclerView 的空数据集指示器未显示
Empty dataset indicator for RecyclerView not showing
我试图在过滤后的 RecyclerView 的数据集包含 0 个项目时显示带有消息的 Snackbar,但由于某种原因,Snackbar 根本没有出现。相关代码是否需要放到Fragment或Adapter中?没有图书馆可以吗?
class MyFragment : androidx.fragment.app.Fragment() {
private lateinit var mRecyclerView: RecyclerView
private var mAdapter: MyAdapter? = null
private lateinit var mSearchView: SearchView
private lateinit var mSearchMenuItem: MenuItem
private val myList = ArrayList<Item>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.recycler_view, container, false)
mRecyclerView = view.findViewById(R.id.myRecyclerView)
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager =
androidx.recyclerview.widget.LinearLayoutManager(this.activity)
mRecyclerView.addItemDecoration(
androidx.recyclerview.widget.DividerItemDecoration(
context, LinearLayout.VERTICAL
)
)
myList.add(
Item(
getString(R.string.item_a)
)
)
mAdapter = MyAdapter(requireActivity(), myList)
mRecyclerView.adapter = mAdapter
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val mSnackbar = Snackbar.make(
requireView(),
getString(R.string.no_items),
Snackbar.LENGTH_LONG
)
mSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
mAdapter!!.filter.filter(newText)
mAdapter!!.notifyDataSetChanged()
if (mAdapter!!.itemCount <1) {
mSnackbar.show()
} else {
mSnackbar.dismiss()
}
return false
}
})
super.onCreateOptionsMenu(menu, inflater)
}
}
适配器代码
class MyAdapter(
private val mCtx: Context,
var myList: MutableList<Item>,
) : androidx.recyclerview.widget.RecyclerView.Adapter<MyAdapter.MyViewHolder>(), Filterable {
private val myListFull = myList.toMutableList()
val mSnackbar = Snackbar.make(
requireView(),
getString(R.string.my_message),
Snackbar.LENGTH_INDEFINITE
)
private val companyFilter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val filteredList = ArrayList<Item>()
if (constraint == null || constraint.isEmpty()) {
filteredList.addAll(myListFull)
} else {
val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in myListFull) {
if (item.Name.toLowerCase().contains(filterPattern)
) {
filteredList.add(item)
}
}
}
val results = FilterResults()
results.values = filteredList
return results
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
myList.clear()
myList.addAll(results!!.values as List<Item>)
notifyDataSetChanged()
if (filteredList.isEmpty()) {
mSnackbar.show()
} else {
mSnackbar.dismiss()
}
}
}
private fun String.matchesIgnoreCase(otherString: String): Boolean {
return this.toLowerCase().contains(otherString.trim().toLowerCase())
}
class MyViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
.ViewHolder(itemView) {
var tvTitle: TextView = itemView.findViewById(R.id.title)
var tvSubtitle: TextView = itemView.findViewById(R.id.subtitle)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val inflater = LayoutInflater.from(mCtx)
val v = inflater.inflate(R.layout.list_item, parent, false)
return MyViewHolder(v)
}
override fun getItemCount(): Int {
return myList.size
}
override fun getFilter(): Filter {
return companyFilter
}
}
我猜是 this:
Filtering operations performed by calling filter(java.lang.CharSequence)
or filter(java.lang.CharSequence, android.widget.Filter.FilterListener)
are performed asynchronously. When these methods are called, a filtering request is posted in a request queue and processed later.
因此您在调用 filter
后立即检查 myList
(通过 getItemCount
),并且数据尚未更新,因为过滤/发布内容尚未完成运行。所以你的小吃店被解雇了
publishResults
方法在 UI 线程上运行,所以如果需要,可以在那里显示快餐栏?
我试图在过滤后的 RecyclerView 的数据集包含 0 个项目时显示带有消息的 Snackbar,但由于某种原因,Snackbar 根本没有出现。相关代码是否需要放到Fragment或Adapter中?没有图书馆可以吗?
class MyFragment : androidx.fragment.app.Fragment() {
private lateinit var mRecyclerView: RecyclerView
private var mAdapter: MyAdapter? = null
private lateinit var mSearchView: SearchView
private lateinit var mSearchMenuItem: MenuItem
private val myList = ArrayList<Item>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.recycler_view, container, false)
mRecyclerView = view.findViewById(R.id.myRecyclerView)
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager =
androidx.recyclerview.widget.LinearLayoutManager(this.activity)
mRecyclerView.addItemDecoration(
androidx.recyclerview.widget.DividerItemDecoration(
context, LinearLayout.VERTICAL
)
)
myList.add(
Item(
getString(R.string.item_a)
)
)
mAdapter = MyAdapter(requireActivity(), myList)
mRecyclerView.adapter = mAdapter
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val mSnackbar = Snackbar.make(
requireView(),
getString(R.string.no_items),
Snackbar.LENGTH_LONG
)
mSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
mAdapter!!.filter.filter(newText)
mAdapter!!.notifyDataSetChanged()
if (mAdapter!!.itemCount <1) {
mSnackbar.show()
} else {
mSnackbar.dismiss()
}
return false
}
})
super.onCreateOptionsMenu(menu, inflater)
}
}
适配器代码
class MyAdapter(
private val mCtx: Context,
var myList: MutableList<Item>,
) : androidx.recyclerview.widget.RecyclerView.Adapter<MyAdapter.MyViewHolder>(), Filterable {
private val myListFull = myList.toMutableList()
val mSnackbar = Snackbar.make(
requireView(),
getString(R.string.my_message),
Snackbar.LENGTH_INDEFINITE
)
private val companyFilter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val filteredList = ArrayList<Item>()
if (constraint == null || constraint.isEmpty()) {
filteredList.addAll(myListFull)
} else {
val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in myListFull) {
if (item.Name.toLowerCase().contains(filterPattern)
) {
filteredList.add(item)
}
}
}
val results = FilterResults()
results.values = filteredList
return results
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
myList.clear()
myList.addAll(results!!.values as List<Item>)
notifyDataSetChanged()
if (filteredList.isEmpty()) {
mSnackbar.show()
} else {
mSnackbar.dismiss()
}
}
}
private fun String.matchesIgnoreCase(otherString: String): Boolean {
return this.toLowerCase().contains(otherString.trim().toLowerCase())
}
class MyViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
.ViewHolder(itemView) {
var tvTitle: TextView = itemView.findViewById(R.id.title)
var tvSubtitle: TextView = itemView.findViewById(R.id.subtitle)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val inflater = LayoutInflater.from(mCtx)
val v = inflater.inflate(R.layout.list_item, parent, false)
return MyViewHolder(v)
}
override fun getItemCount(): Int {
return myList.size
}
override fun getFilter(): Filter {
return companyFilter
}
}
我猜是 this:
Filtering operations performed by calling
filter(java.lang.CharSequence)
orfilter(java.lang.CharSequence, android.widget.Filter.FilterListener)
are performed asynchronously. When these methods are called, a filtering request is posted in a request queue and processed later.
因此您在调用 filter
后立即检查 myList
(通过 getItemCount
),并且数据尚未更新,因为过滤/发布内容尚未完成运行。所以你的小吃店被解雇了
publishResults
方法在 UI 线程上运行,所以如果需要,可以在那里显示快餐栏?