安卓下拉刷新、上拉加载小结

下拉刷新、上拉加载在安卓里面简直就是无处不在,可是不知道为什么谷歌不直接提供一个这样的控件,网上相关的文章应该多的数不清了,我这只是简单给自己总结一个。

最佳办法

要说最佳办法肯定是用别人稳定的开源库了,我这就直接推荐鼎鼎大名的 SmartRefreshLayout 了

https://github.com/scwang90/SmartRefreshLayout

简单讲下用法吧,看下面:

implementation  'com.scwang.smart:refresh-layout-kernel:2.0.3'  

这里有部分限制,具体可以看 github 文档,我这是 androidx 简单使用就加这一个。

<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smart.refresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/refreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.scwang.smart.refresh.header.ClassicsHeader
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:background="#fff" />
    <com.scwang.smart.refresh.footer.ClassicsFooter
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</com.scwang.smart.refresh.layout.SmartRefreshLayout>

RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout);
refreshLayout.setRefreshHeader(new ClassicsHeader(this));
refreshLayout.setRefreshFooter(new ClassicsFooter(this));
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
    @Override
    public void onRefresh(RefreshLayout refreshlayout) {
        refreshlayout.finishRefresh(2000/*,false*/);//传入false表示刷新失败
    }
});
refreshLayout.setOnLoadMoreListener(new onl oadMoreListener() {
    @Override
    public void onl oadMore(RefreshLayout refreshlayout) {
        refreshlayout.finishLoadMore(2000/*,false*/);//传入false表示加载失败
    }
});

差劲办法

差劲的办法就是自己搞一套(当然写得好另说,写不好就是差劲),虽然不是很难,也好理解,但是交接给别人,真的可以把头搞大,这也是我写这篇文章的原因之一,就不多说了。

简单用法

有时候不想引入太多的库,又不想自己搞一套,就可以参考下面我这种方法了。

这里也用到了一个大名鼎鼎的开源库 BaseRecyclerViewAdapterHelper,具体使用方法可以谷歌搜索一下。我的思路是使用谷歌官方的 SwipeRefreshLayout 配合 BaseRecyclerViewAdapterHelper 共同实现上拉刷新和下拉加载的,也是 BaseRecyclerViewAdapterHelper 所推荐的方法。其中 SwipeRefreshLayout 用以实现下拉刷新,而 BaseRecyclerViewAdapterHelper 用来实现上拉加载,代码肯定比用别人开源库复杂点,但是还是挺简单的,下面看用法:

  • XML 布局文件
    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/list_trajectory"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:cacheColorHint="@null"
            android:divider="@null"
            android:dividerHeight="@dimen/edge_distance_small"/>

    </android.support.v4.widget.SwipeRefreshLayout>
  • Java 代码
   
    RecyclerView recyclerView;

    SwipeRefreshLayout refreshLayout;

    private ItemAdapter adapter;    //列表适配器

    private boolean isReload = false;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
    	
        ...
            
        //设置下拉控件
        initRefreshLayout();

        //设置列表及适配器
        initRecyclerView();
    }

   private void initRefreshLayout() {
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                isReload = true;
        		refreshLayout.setRefreshing(true);
        		adapter.setEnableLoadMore(false);
                //加载数据
				...
            }
        });
    }

    private void initRecyclerView() {
        //设置recyclerView
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        //设置列表适配器
        adapter = new ItemAdapter(R.layout.item, mData);
        //设置空布局
        adapter.setEmptyView(R.layout.item_empty, (ViewGroup) recyclerView.getParent());

        //启用上拉刷新
        adapter.setEnableLoadMore(true);
        adapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onl oadMoreRequested() {
                refreshLayout.setEnabled(false);
                //获取数据
                ...
            }
        },recyclerView);
        recyclerView.setAdapter(adapter);
    }

	//获取数据成功
    public void onSuccess(String msg, List<Item> data) {
        //继续加载
        if (isReload) {
            mData.clear();
            isReload = false;
        }
        mData.addAll(data);
        adapter.loadMoreComplete();
        adapter.notifyDataSetChanged();
        adapter.setEnableLoadMore(true);
        refreshLayout.setRefreshing(false);
        //这里设置了一页20条数据
        if (data.size() < 20) {
            adapter.loadMoreEnd();
        }
    }

	//获取数据失败
    public void onFailed(String msg, int errCode) {
        adapter.loadMoreComplete();
        adapter.setEnableLoadMore(true);
        refreshLayout.setRefreshing(false);
    }

写的不是很清楚,主要有下面几点要理解

  1. 下拉刷新和上拉加载状态交替问题

    这两个状态不能同时出现,需要在请求数据和结束请求数据的时候,改变 refreshLayout 和 adapter 的状态,具体看下面代码:

    refreshLayout.setRefreshing(true);
    adapter.setEnableLoadMore(false);
    
  2. 加载数据完成和加载数据结束

    在 BaseRecyclerViewAdapterHelper 中提供了两种方法,一个是 loadMoreComplete,表示单次的数据请求加载完成,底部 footer 不再显示,另一个是 loadMoreEnd,表示数据全部加载完成,不会再触发上拉加载了,这个尤其注意无论成功或者失败,都应该调用 loadMoreComplete 方法,而全部数据加载了要调用 loadMoreEnd 方法。

结语

这里讲了三种实现下拉刷新、上拉加载的方法,看需要使用吧。

end

上一篇:使用DataAdapter把数据库数据填充到DataSet并把修改的数据更新到数据库、数据显示控件DataGridView


下一篇:vmware-workstation