大家都知道listView提供了一个setEmptyView(View view)用来处理当获取不到数据的时候的界面处理——-用于做些数据为空的提示。
但是我们也很遗憾的发现RecyclerView并没有提供像listView那样的setEmptyView()方法。不过办法自然是有的。 一般有两种方式:
- 1.在布局文件中控制RecyclerView控件和空布局的显示和隐藏
- 2.重写RecyclerView.Adapter(推荐)
第一种思路自然low了一点,虽然listview也是采用这种思路,不信你可以看看listview源码。所以这里,我只讲第二种思路的实现方式。
思路:
- 空布局做成一个item,通过getItemCount()返回结果判断, 当List集合没有数据,返回1,这样就显示空布局item
- 用getItemViewType(int position) 判断,空布局类型返回0,正常布局类型返回1
- 在onCreateViewHolder和onBindViewHolder通过判断ViewType在进行对应布局的创建和初始化。
以下是自定义adapter的源码,很简单,这边就不详细讲解了。
internal inner class HomeAdapter : RecyclerView.Adapter<HomeAdapter.HomeViewHolder?>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeViewHolder {
val itemView: View = LayoutInflater.from(this@RecyclerviewActivity)
.inflate(R.layout.item_rv_txt, parent, false)
val holder = HomeViewHolder(itemView)
itemView.setOnClickListener { v ->
mOnItemClickListener?.onItemClick(v, holder, holder.adapterPosition)
}
itemView.setOnLongClickListener(View.OnLongClickListener { v ->
if (mOnItemClickListener != null) {
return@OnLongClickListener mOnItemClickListener!!.onItemLongClick(v, holder, holder.adapterPosition)
}
false
})
return holder
}
override fun onBindViewHolder(holder: HomeViewHolder, position: Int) {
holder.tv.text = mDatas[position]
}
internal inner class HomeViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var tv: TextView = view.findViewById(R.id.txt)
}
override fun getItemCount(): Int {
return mDatas.size
}
var mOnItemClickListener: OnItemClickListener? = null
fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) {
mOnItemClickListener = onItemClickListener
}
}
特别注意,如果recyclerview的LayoutManager为LinearLayoutManager,上面的空布局显示肯定是没有问题的,那么如果是GridLayoutManager和StaggeredGridLayoutManager呢,在spanCount不为1的情况,即不为单列的情况,就会出现empty view不能居中的问题。
当然,也很好解决。 对应GridLayoutManager,提供了如下方法
//设置表格,根据position计算在该position处item的跨度(占几列数据)
layoutManager!!.setSpanSizeLookup(object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
//计算在哪个position更换跨度,要占满一行跨度就是2
return if (mDatas.size > 0) {
1
} else {
2
}
}
})
可以根据返回的int,通知布局可以跨几个列显示。假设我们的表格布局为2列,如果没有数据的时候,让empytview的item跨2个列,这样emptyview就可以居中显示了。以上代码也很容易理解。 StaggeredGridLayoutManager并没有以上setSpanSizeLookup的方法,不过也可以解决,可以在Adapter.notifyDataSetChanged()方法之前,先判断数据集的数量,可以setSpanCount()设置布局的列数。代码如下
if (mDatas.size() == 0){
layoutManager.setSpanCount(1);
}else {
layoutManager.setSpanCount(2);
}
homeAdapter.notifyDataSetChanged();
至此,recyclerview的空布局问题就完美解决了。
git地址: https://gitee.com/stonezry/AndroidDemo
欢迎关注本人公众号和小程序,谢谢