RecyclerView实现空视图切换

实际的业务需求中:无列表数据的时候,我们希望显示一个空视图布局,以方便用户直观理解;而当有数据时,则正常加载列表数据。

这样就形成了一个有数据和无数据的布局切换。基于此,本文提供了一种解决方案。

一张没有感情的效果图。
在这里插入图片描述

实现步骤:

1、重写RecyclerView

class SupportEmptyRecyclerView : RecyclerView {

    constructor(context: Context?)
            : super(context!!)

    constructor(context: Context?, attrs: AttributeSet?)
            : super(context!!, attrs)

    constructor(context: Context?, attrs: AttributeSet?, defStyle: Int)
            : super(context!!, attrs, defStyle)


    private var mEmptyView: View? = null

    /**
     * * @param emptyView 设置空视图
     */
    fun setEmptyView(emptyView: View?) {
        mEmptyView = emptyView
    }

    /**
     * 注册观察者
     */
    override fun setAdapter(adapter: Adapter<*>?) {
        super.setAdapter(adapter)
        adapter?.registerAdapterDataObserver(emptyObserver)
    }

    /**
     * 移除观察字
     */
    fun removeObserver() {
        adapter?.unregisterAdapterDataObserver(emptyObserver)
    }

    /**
     * 创建一个RecyclerView自带的观察者,重写onChange函数
     * * 我们大可以在这个观察者这里判断我们的逻辑,就是显示隐藏
     */
    private val emptyObserver: AdapterDataObserver = object : AdapterDataObserver() {
        override fun onChanged() {
            val adapter = adapter
            //判断数据为空否,进行显示或者隐藏
            if (null != adapter && null != mEmptyView) {
                if (0 == adapter.itemCount) {
                    mEmptyView!!.visibility = View.VISIBLE
                    this@SupportEmptyRecyclerView.visibility = View.GONE
                } else {
                    mEmptyView!!.visibility = View.GONE
                    this@SupportEmptyRecyclerView.visibility = View.VISIBLE
                }
            }
        }
    }

}

2、布局中添加空视图布局

<LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <com.scjzbd.mvvmbase.ui.project.view.SupportEmptyRecyclerView
                    android:id="@+id/pa_rv"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

                <!--todo 自定义的空布局-->
                <include
                    android:id="@+id/empty_view"
                    layout="@layout/layout_empty_view"
                    android:visibility="gone" />
            </LinearLayout>

3、调用设置空视图方法

binding.paRv.setEmptyView(binding.emptyView)

4、关键点说明

利用RecyclerView 自带的观察者 AdapterDataObserver ,实现对数据变化的通知。

再设置适配器的时候,注册观察者:

adapter?.registerAdapterDataObserver(emptyObserver)

当我们调用适配的,notifyDataSetChanged方法时,会通知已注册的观察者,并进入观察者的onChanged函数。

onChanged函数主要是根据数据适配器adapter.itemCount的数量,来判断数据是否需要切换空视图布局(显示/隐藏 的方式)。






原创不易,求个关注。

在这里插入图片描述

微信公众号:一粒尘埃的漫旅
里面有很多想对大家说的话,就像和朋友聊聊天。
写代码,做设计,聊生活,聊工作,聊职场。
我见到的世界是什么样子的?
搜索关注我吧。

公众号与博客的内容不同。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android RecyclerView实现轮播可以通过以下步骤完成: 1. 创建一个 RecyclerView,并设置它的布局管理器为 LinearLayoutManager,并将它的方向设置为横向。 2. 创建一个自定义的 RecyclerView.Adapter,继承自 RecyclerView.Adapter<VH>,其中 VH 是一个 ViewHolder 类型,用于管理 RecyclerView 的子项视图。 3. 在 Adapter 中创建一个 List,用于存储轮播数据源。 4. 在 onCreateViewHolder() 方法中创建 ViewHolder,并返回它。 5. 在 onBindViewHolder() 方法中绑定 ViewHolder,并将轮播数据展示在该 ViewHolder 上。 6. 在 getItemCount() 方法中返回数据源的大小。 7. 使用 Timer 和 TimerTask 实现轮播效果,每隔一定时间切换到下一个轮播。 以下是一个简单的实现示例: ```java public class BannerAdapter extends RecyclerView.Adapter<BannerAdapter.ViewHolder> { private List<BannerData> mDataList; public BannerAdapter(List<BannerData> dataList) { mDataList = dataList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_banner, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { BannerData data = mDataList.get(position); holder.imageView.setImageResource(data.getImageResId()); holder.textView.setText(data.getTitle()); } @Override public int getItemCount() { return mDataList.size(); } static class ViewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView textView; ViewHolder(View itemView) { super(itemView); imageView = itemView.findViewById(R.id.iv_banner); textView = itemView.findViewById(R.id.tv_banner_title); } } } ``` 在 Activity 或 Fragment 中,使用 Timer 和 TimerTask 实现轮播效果: ```java public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private BannerAdapter mAdapter; private Timer mTimer; private int mCurrentPosition = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)); List<BannerData> dataList = new ArrayList<>(); dataList.add(new BannerData(R.drawable.banner1, "Banner 1")); dataList.add(new BannerData(R.drawable.banner2, "Banner 2")); dataList.add(new BannerData(R.drawable.banner3, "Banner 3")); mAdapter = new BannerAdapter(dataList); mRecyclerView.setAdapter(mAdapter); mTimer = new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { mCurrentPosition++; if (mCurrentPosition >= mAdapter.getItemCount()) { mCurrentPosition = 0; } mRecyclerView.smoothScrollToPosition(mCurrentPosition); } }); } }, 2000, 2000); } @Override protected void onDestroy() { super.onDestroy(); mTimer.cancel(); } } ``` 在上面的示例中,BannerData 是一个自定义的数据类,用于存储轮播片资源 ID 和标题。在 onCreateViewHolder() 方法中,我们使用 LayoutInflater 创建了一个子项视图,并将其封装在 ViewHolder 中返回。在 onBindViewHolder() 方法中,我们将轮播数据展示在 ViewHolder 中。在 getItemCount() 方法中,我们返回数据源的大小。在 Activity 或 Fragment 中,我们使用 Timer 和 TimerTask 实现轮播效果,每隔 2 秒钟切换到下一个轮播

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值