RecyclerView详解(五):设置EmptyView

大家都知道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() {

        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

欢迎关注本人公众号和小程序,谢谢
在这里插入图片描述

在这里插入图片描述

你可能感兴趣的:(android,android)