RecyclerView添加EmptyView(空布局)

github地址(Demo下载)
https://github.com/zhouxu88/EmptyRecyclerView

一、简介:

在项目中用RecyclerView的时候,发现它不可以像以前使用listView或者gridView时,当列表为空时,显示一个特殊的empty view来提示用户。没关系,我们可以自己来实现这个功能。

三、实现思路

阅读RecyclerView的源码,可以发现里面自带了一个数据观察者AdapterDataObserver用来监听数据的变化(代码在下面),所以我们自然想到了,自定义一个RecyclerView,重写里面的这个类,然后检查数据源的个数是否为0,当为空的时候,把我们先显示的EmptyView显示出来,这个和以前ListView相似。思路比较简单,直接看看代码是怎么实现的。

源码中AdapterDataObserver类

/**
     * Observer base class for watching changes to an {@link Adapter}.
     * See {@link Adapter#registerAdapterDataObserver(AdapterDataObserver)}.
     */
    public static abstract class AdapterDataObserver {
        public void onChanged() {
            // Do nothing
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            // fallback to onItemRangeChanged(positionStart, itemCount) if app
            // does not override this method.
            onItemRangeChanged(positionStart, itemCount);
        }

        public void onItemRangeInserted(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            // do nothing
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            // do nothing
        }
    }

四、自定义RecyclerView

EmptyRecyclerView

public class EmptyRecyclerView extends RecyclerView {

    private View emptyView;
    private static final String TAG = "EmptyRecyclerView";

    final private AdapterDataObserver observer = new AdapterDataObserver() {
        @Override
        public void onChanged() {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            Log.i(TAG, "onItemRangeInserted" + itemCount);
            checkIfEmpty();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkIfEmpty();
        }
    };

    public EmptyRecyclerView(Context context) {
        super(context);
    }

    public EmptyRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EmptyRecyclerView(Context context, AttributeSet attrs,
                             int defStyle) {
        super(context, attrs, defStyle);
    }

    private void checkIfEmpty() {
        if (emptyView != null && getAdapter() != null) {
            final boolean emptyViewVisible =
                    getAdapter().getItemCount() == 0;
            emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
            setVisibility(emptyViewVisible ? GONE : VISIBLE);
        }
    }

    @Override
    public void setAdapter(Adapter adapter) {
        final Adapter oldAdapter = getAdapter();
        if (oldAdapter != null) {
            oldAdapter.unregisterAdapterDataObserver(observer);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerAdapterDataObserver(observer);
        }

        checkIfEmpty();
    }

    //设置没有内容时,提示用户的空布局
    public void setEmptyView(View emptyView) {
        this.emptyView = emptyView;
        checkIfEmpty();
    }
}

重写AdapterDataObserver,每次数据变化都会调用onChanged(),所以就在这里检查数据源是否为空,看一下checkIfEmpty()方法,很简单,就是通过Adapter的getCount来判断时候数据为空,空就显示我们定义的EmptyView。
最后在setAdapter的时候调用如下代码就可以了。

 mRecyclerView.setEmptyView(mEmptyView); //设置空布局注册

MainActivity:

public class MainActivity extends AppCompatActivity {

    private EmptyRecyclerView mRecyclerView;
    private MyRecycleViewAdapter mAdapter;
    private View mEmptyView;
    private List mList; //数据源

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();
        initView();
        initRv();
    }

    private void initView() {
        mRecyclerView = (EmptyRecyclerView) findViewById(R.id.emptyRecyclerView);
        mEmptyView = findViewById(R.id.empty_iv);
        findViewById(R.id.deleteAll_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //删除所有数据
                mList.clear();
                mAdapter.notifyDataSetChanged();
            }
        });
        findViewById(R.id.insert_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //添加10条数据
                for (int i = 0; i < 10; i++) {
                    ItemData itemData = new ItemData("列表" + i);
                    mList.add(itemData);
                }
                mAdapter.notifyDataSetChanged();
            }
        });
    }

    //插入数据
    private void initData() {
        mList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            ItemData itemData = new ItemData("列表" + i);
            mList.add(itemData);
        }
    }

//初始化RecyclerView    
private void initRv() {
        mAdapter = new MyRecycleViewAdapter(this, mList);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setEmptyView(mEmptyView); //设置空布局,这是关键
    }
}

布局文件 activity_main.xml




    

你可能感兴趣的:(RecyclerView添加EmptyView(空布局))