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