[49→100]那些年用过的下拉刷新、上拉加载更多的库

移动端开发,不联网的App少之又少,所以下拉刷新数据、上拉加载更多数据作为一个基础功能,相关的库层出不穷,这里就记录一下曾经用过的库吧,希望对大家有用。

一、 Android-PullToRefresh

这是最经典的下拉刷新库了。在github上有6952个Star、4746个Fork。在用eclipse开发Android的时代,是必备使用的库之一。

集成方式也很简单。

  1. eclipse导入lib 源码
  2. 显示代码:


  1. 控制代码:
// Set a listener to be invoked when the list should be refreshed.
PullToRefreshListView pullToRefreshView = (PullToRefreshListView) findViewById(R.id.pull_to_refresh_listview);
pullToRefreshView.setOnRefreshListener(new OnRefreshListener() {
    @Override
    public void onRefresh(PullToRefreshBase refreshView) {
        // Do work to refresh the list here.
        new GetDataTask().execute();
    }
});

private class GetDataTask extends AsyncTask {
    ...
    @Override
    protected void onPostExecute(String[] result) {
        // Call onRefreshComplete when the list has been refreshed.
        pullToRefreshView.onRefreshComplete();
        super.onPostExecute(result);
    }
}

遗憾的是,这个项目不再维护,最后一次更新日期为2013年2月2号,在Android开发已经进化到gradle一行导包的时代,只能放弃它了。

二、android-Ultra-Pull-To-Refresh

这是国内Android开发大神廖祜秋开发的一个开源库。特点是内置各种下拉刷新交互风格。

  • 下拉刷新(iOS风格)

    [49→100]那些年用过的下拉刷新、上拉加载更多的库_第1张图片
  • 释放刷新(经典风格)

    [49→100]那些年用过的下拉刷新、上拉加载更多的库_第2张图片
  • 刷新时,头部保持(新浪微博)

    [49→100]那些年用过的下拉刷新、上拉加载更多的库_第3张图片
  • 刷新时,头部不保持(微信朋友圈)

    [49→100]那些年用过的下拉刷新、上拉加载更多的库_第4张图片
  • 自动刷新,进入界面时自动刷新

集成方式很简单:

  1. 一行导包
compile 'in.srain.cube:ultra-ptr:1.0.11'
  1. 界面逻辑:


        
    

  1. 控制逻辑:
ptrFrame.setPtrHandler(new PtrHandler() {
    @Override
    public void onRefreshBegin(PtrFrameLayout frame) {
        frame.postDelayed(new Runnable() {
            @Override
            public void run() {
                ptrFrame.refreshComplete();
            }
        }, 1800);
    }

    @Override
    public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
        // 默认实现,根据实际情况做改动
        return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
    }
});

相关原理可以参考作者写的文档——我眼中的下拉刷新

遗憾的是这个库不支持上拉加载更多,作者有提供一个解决方案——android-cube-app,但是这个解决方案是一个demo,而不是内嵌在Ultra-Pull-To-Refresh中,不符合一行导包的原则了。

三、BGARefreshLayout-Android

这个库同时支持下拉刷新和上拉加载更多,集成也很简单:

  1. 一行导包
dependencies {
    compile 'com.android.support:recyclerview-v7:latestVersion'
    // 记得添加nineoldandroids
    compile 'com.nineoldandroids:library:2.4.0'
    compile 'cn.bingoogolapple:bga-refreshlayout:latestVersion@aar'
}
  1. 界面逻辑:

    
    

  1. 控制逻辑:
// 让activity或者fragment实现BGARefreshLayoutDelegate接口
public class ModuleNameActivity extends AppCompatActivity implements BGARefreshLayout.BGARefreshLayoutDelegate {
    private BGARefreshLayout mRefreshLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_moudlename);
        initRefreshLayout();
    }
    private void initRefreshLayout(BGARefreshLayout refreshLayout) {
        mRefreshLayout = (BGARefreshLayout) findViewById(R.id.rl_modulename_refresh);
        // 为BGARefreshLayout设置代理
        mRefreshLayout.setDelegate(this);
        // 设置下拉刷新和上拉加载更多的风格     参数1:应用程序上下文,参数2:是否具有上拉加载更多功能
        BGARefreshViewHolder refreshViewHolder = new XXXImplRefreshViewHolder(this, true))
        // 设置下拉刷新和上拉加载更多的风格
        mRefreshLayout.setRefreshViewHolder(refreshViewHolder);
        // 为了增加下拉刷新头部和加载更多的通用性,提供了以下可选配置选项  -------------START
        // 设置正在加载更多时不显示加载更多控件
        // mRefreshLayout.setIsShowLoadingMoreView(false);
        // 设置正在加载更多时的文本
        refreshViewHolder.setLoadingMoreText(loadingMoreText);
        // 设置整个加载更多控件的背景颜色资源id
        refreshViewHolder.setLoadMoreBackgroundColorRes(loadMoreBackgroundColorRes);
        // 设置整个加载更多控件的背景drawable资源id
        refreshViewHolder.setLoadMoreBackgroundDrawableRes(loadMoreBackgroundDrawableRes);
        // 设置下拉刷新控件的背景颜色资源id
        refreshViewHolder.setRefreshViewBackgroundColorRes(refreshViewBackgroundColorRes);
        // 设置下拉刷新控件的背景drawable资源id
        refreshViewHolder.setRefreshViewBackgroundDrawableRes(refreshViewBackgroundDrawableRes);
        // 设置自定义头部视图(也可以不用设置)     参数1:自定义头部视图(例如广告位), 参数2:上拉加载更多是否可用
        mRefreshLayout.setCustomHeaderView(mBanner, false);
        // 可选配置  -------------END
    }
    @Override
    public void onBGARefreshLayoutBeginRefreshing(BGARefreshLayout refreshLayout) {
        // 在这里加载最新数据

        if (mIsNetworkEnabled) {
            // 如果网络可用,则加载网络数据
            new AsyncTask() {

                @Override
                protected Void doInBackground(Void... params) {
                    try {
                        Thread.sleep(MainActivity.LOADING_DURATION);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    // 加载完毕后在UI线程结束下拉刷新
                    mRefreshLayout.endRefreshing();
                    mDatas.addAll(0, DataEngine.loadNewData());
                    mAdapter.setDatas(mDatas);
                }
            }.execute();
        } else {
            // 网络不可用,结束下拉刷新
            Toast.makeText(this, "网络不可用", Toast.LENGTH_SHORT).show();
            mRefreshLayout.endRefreshing();
        }
    }

    @Override
    public boolean onBGARefreshLayoutBeginLoadingMore(BGARefreshLayout refreshLayout) {
        // 在这里加载更多数据,或者更具产品需求实现上拉刷新也可以

        if (mIsNetworkEnabled) {
            // 如果网络可用,则异步加载网络数据,并返回true,显示正在加载更多
            new AsyncTask() {

                @Override
                protected Void doInBackground(Void... params) {
                    try {
                        Thread.sleep(MainActivity.LOADING_DURATION);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    // 加载完毕后在UI线程结束加载更多
                    mRefreshLayout.endLoadingMore();
                    mAdapter.addDatas(DataEngine.loadMoreData());
                }
            }.execute();

            return true;
        } else {
            // 网络不可用,返回false,不显示正在加载更多
            Toast.makeText(this, "网络不可用", Toast.LENGTH_SHORT).show();
            return false;
        }
    }
    // 通过代码方式控制进入正在刷新状态。应用场景:某些应用在activity的onStart方法中调用,自动进入正在刷新状态获取最新数据
    public void beginRefreshing() {
        mRefreshLayout.beginRefreshing();
    }
    // 通过代码方式控制进入加载更多状态
    public void beginLoadingMore() {
        mRefreshLayout.beginLoadingMore();
    }
}

但这个库有一个严重的bug

正在刷新或加载更多时,用户上下滑动不会让下拉刷新视图和加载更多视图跟着滑动

这一点在网络慢的时候,非常影响用户体验

四、CommonPullToRefresh

这个库基于android-Ultra-Pull-To-Refresh,封装了加载更多的逻辑,而且还支持Android最新推出的下拉控件** SwipeRefreshLayout**

[49→100]那些年用过的下拉刷新、上拉加载更多的库_第5张图片
SwipeRefreshLayout

集成步骤同样简单:

  1. 一行导包
compile 'com.chanven.lib:cptr:1.0.0'
  1. 界面逻辑


    

        
    

  1. 控制逻辑
    这一块可以使用android-Ultra-Pull-To-Refresh的方式,也可以使用** SwipeRefreshLayout**的方式,看需求了。

我现在选择的下拉刷新库就是CommonPullToRefresh,目前使用中还没有发现问题。

Panda
2016-06-13

你可能感兴趣的:([49→100]那些年用过的下拉刷新、上拉加载更多的库)