[49→100]那些年用過的下拉刷新胧瓜、上拉加載更多的庫

移動(dòng)端開發(fā)矢棚,不聯(lián)網(wǎng)的App少之又少,所以下拉刷新數(shù)據(jù)府喳、上拉加載更多數(shù)據(jù)作為一個(gè)基礎(chǔ)功能蒲肋,相關(guān)的庫層出不窮,這里就記錄一下曾經(jīng)用過的庫吧钝满,希望對大家有用兜粘。

一、 Android-PullToRefresh

這是最經(jīng)典的下拉刷新庫了弯蚜。在github上有6952個(gè)Star孔轴、4746個(gè)Fork。在用eclipse開發(fā)Android的時(shí)代碎捺,是必備使用的庫之一路鹰。

集成方式也很簡單。

  1. eclipse導(dǎo)入lib 源碼
  2. 顯示代碼:
<!--
  The PullToRefreshListView replaces a standard ListView widget.
  The ID CAN NOT be @+id/android:list
-->
<com.handmark.pulltorefresh.library.PullToRefreshListView
    android:id="@+id/pull_to_refresh_listview"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent" />
  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<ListView>() {
    @Override
    public void onRefresh(PullToRefreshBase<ListView> refreshView) {
        // Do work to refresh the list here.
        new GetDataTask().execute();
    }
});

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

遺憾的是收厨,這個(gè)項(xiàng)目不再維護(hù)晋柱,最后一次更新日期為2013年2月2號(hào),在Android開發(fā)已經(jīng)進(jìn)化到gradle一行導(dǎo)包的時(shí)代诵叁,只能放棄它了雁竞。

二、android-Ultra-Pull-To-Refresh

這是國內(nèi)Android開發(fā)大神廖祜秋開發(fā)的一個(gè)開源庫拧额。特點(diǎn)是內(nèi)置各種下拉刷新交互風(fēng)格碑诉。

  • 下拉刷新(iOS風(fēng)格)

    <div>
    </div>
  • 釋放刷新(經(jīng)典風(fēng)格)

    <div>
    </div>
  • 刷新時(shí),頭部保持(新浪微博)

  • 刷新時(shí)势腮,頭部不保持(微信朋友圈)

  • 自動(dòng)刷新联贩,進(jìn)入界面時(shí)自動(dòng)刷新

    </div>

集成方式很簡單:

  1. 一行導(dǎo)包
compile 'in.srain.cube:ultra-ptr:1.0.11'
  1. 界面邏輯:
<in.srain.cube.views.ptr.PtrFrameLayout
    android:id="@+id/store_house_ptr_frame"
    xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    cube_ptr:ptr_resistance="1.7"
    cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
    cube_ptr:ptr_duration_to_close="300"
    cube_ptr:ptr_duration_to_close_header="2000"
    cube_ptr:ptr_keep_header_when_refresh="true"
    cube_ptr:ptr_pull_to_fresh="false" >
<LinearLayout
        android:id="@+id/store_house_ptr_image_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/cube_mints_333333"
        android:clickable="true"
        android:padding="10dp">
        <in.srain.cube.image.CubeImageView
            android:id="@+id/store_house_ptr_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
</in.srain.cube.views.ptr.PtrFrameLayout>
  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) {
        // 默認(rèn)實(shí)現(xiàn),根據(jù)實(shí)際情況做改動(dòng)
        return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
    }
});

相關(guān)原理可以參考作者寫的文檔——我眼中的下拉刷新

遺憾的是這個(gè)庫不支持上拉加載更多捎拯,作者有提供一個(gè)解決方案——android-cube-app泪幌,但是這個(gè)解決方案是一個(gè)demo盲厌,而不是內(nèi)嵌在Ultra-Pull-To-Refresh中,不符合一行導(dǎo)包的原則了祸泪。

三吗浩、BGARefreshLayout-Android

這個(gè)庫同時(shí)支持下拉刷新和上拉加載更多,集成也很簡單:

  1. 一行導(dǎo)包
dependencies {
    compile 'com.android.support:recyclerview-v7:latestVersion'
    // 記得添加nineoldandroids
    compile 'com.nineoldandroids:library:2.4.0'
    compile 'cn.bingoogolapple:bga-refreshlayout:latestVersion@aar'
}
  1. 界面邏輯:
<cn.bingoogolapple.refreshlayout.BGARefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_modulename_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 內(nèi)容控件 -->
    <AnyView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</cn.bingoogolapple.refreshlayout.BGARefreshLayout>
  1. 控制邏輯:
// 讓activity或者fragment實(shí)現(xiàn)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設(shè)置代理
        mRefreshLayout.setDelegate(this);
        // 設(shè)置下拉刷新和上拉加載更多的風(fēng)格     參數(shù)1:應(yīng)用程序上下文没隘,參數(shù)2:是否具有上拉加載更多功能
        BGARefreshViewHolder refreshViewHolder = new XXXImplRefreshViewHolder(this, true))
        // 設(shè)置下拉刷新和上拉加載更多的風(fēng)格
        mRefreshLayout.setRefreshViewHolder(refreshViewHolder);
        // 為了增加下拉刷新頭部和加載更多的通用性懂扼,提供了以下可選配置選項(xiàng)  -------------START
        // 設(shè)置正在加載更多時(shí)不顯示加載更多控件
        // mRefreshLayout.setIsShowLoadingMoreView(false);
        // 設(shè)置正在加載更多時(shí)的文本
        refreshViewHolder.setLoadingMoreText(loadingMoreText);
        // 設(shè)置整個(gè)加載更多控件的背景顏色資源id
        refreshViewHolder.setLoadMoreBackgroundColorRes(loadMoreBackgroundColorRes);
        // 設(shè)置整個(gè)加載更多控件的背景drawable資源id
        refreshViewHolder.setLoadMoreBackgroundDrawableRes(loadMoreBackgroundDrawableRes);
        // 設(shè)置下拉刷新控件的背景顏色資源id
        refreshViewHolder.setRefreshViewBackgroundColorRes(refreshViewBackgroundColorRes);
        // 設(shè)置下拉刷新控件的背景drawable資源id
        refreshViewHolder.setRefreshViewBackgroundDrawableRes(refreshViewBackgroundDrawableRes);
        // 設(shè)置自定義頭部視圖(也可以不用設(shè)置)     參數(shù)1:自定義頭部視圖(例如廣告位), 參數(shù)2:上拉加載更多是否可用
        mRefreshLayout.setCustomHeaderView(mBanner, false);
        // 可選配置  -------------END
    }
    @Override
    public void onBGARefreshLayoutBeginRefreshing(BGARefreshLayout refreshLayout) {
        // 在這里加載最新數(shù)據(jù)

        if (mIsNetworkEnabled) {
            // 如果網(wǎng)絡(luò)可用右蒲,則加載網(wǎng)絡(luò)數(shù)據(jù)
            new AsyncTask<Void, Void, Void>() {

                @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線程結(jié)束下拉刷新
                    mRefreshLayout.endRefreshing();
                    mDatas.addAll(0, DataEngine.loadNewData());
                    mAdapter.setDatas(mDatas);
                }
            }.execute();
        } else {
            // 網(wǎng)絡(luò)不可用阀湿,結(jié)束下拉刷新
            Toast.makeText(this, "網(wǎng)絡(luò)不可用", Toast.LENGTH_SHORT).show();
            mRefreshLayout.endRefreshing();
        }
    }

    @Override
    public boolean onBGARefreshLayoutBeginLoadingMore(BGARefreshLayout refreshLayout) {
        // 在這里加載更多數(shù)據(jù),或者更具產(chǎn)品需求實(shí)現(xiàn)上拉刷新也可以

        if (mIsNetworkEnabled) {
            // 如果網(wǎng)絡(luò)可用瑰妄,則異步加載網(wǎng)絡(luò)數(shù)據(jù)陷嘴,并返回true,顯示正在加載更多
            new AsyncTask<Void, Void, Void>() {

                @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線程結(jié)束加載更多
                    mRefreshLayout.endLoadingMore();
                    mAdapter.addDatas(DataEngine.loadMoreData());
                }
            }.execute();

            return true;
        } else {
            // 網(wǎng)絡(luò)不可用间坐,返回false灾挨,不顯示正在加載更多
            Toast.makeText(this, "網(wǎng)絡(luò)不可用", Toast.LENGTH_SHORT).show();
            return false;
        }
    }
    // 通過代碼方式控制進(jìn)入正在刷新狀態(tài)。應(yīng)用場景:某些應(yīng)用在activity的onStart方法中調(diào)用竹宋,自動(dòng)進(jìn)入正在刷新狀態(tài)獲取最新數(shù)據(jù)
    public void beginRefreshing() {
        mRefreshLayout.beginRefreshing();
    }
    // 通過代碼方式控制進(jìn)入加載更多狀態(tài)
    public void beginLoadingMore() {
        mRefreshLayout.beginLoadingMore();
    }
}

但這個(gè)庫有一個(gè)嚴(yán)重的bug

正在刷新或加載更多時(shí)劳澄,用戶上下滑動(dòng)不會(huì)讓下拉刷新視圖和加載更多視圖跟著滑動(dòng)

這一點(diǎn)在網(wǎng)絡(luò)慢的時(shí)候,非常影響用戶體驗(yàn)

四蜈七、CommonPullToRefresh

這個(gè)庫基于android-Ultra-Pull-To-Refresh秒拔,封裝了加載更多的邏輯,而且還支持Android最新推出的下拉控件** SwipeRefreshLayout**

SwipeRefreshLayout

集成步驟同樣簡單:

  1. 一行導(dǎo)包
compile 'com.chanven.lib:cptr:1.0.0'
  1. 界面邏輯
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <com.chanven.lib.cptr.PtrClassicFrameLayout
        android:id="@+id/test_list_view_frame"
        xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f0f0f0"
        cube_ptr:ptr_resistance="1.7"
        cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
        cube_ptr:ptr_duration_to_close="200"
        cube_ptr:ptr_duration_to_close_header="1000"
        cube_ptr:ptr_keep_header_when_refresh="true"
        cube_ptr:ptr_pull_to_fresh="false">

        <ListView
            android:id="@+id/test_list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            android:choiceMode="singleChoice"
            android:divider="#b0b0b0"
            android:dividerHeight="0.1dp"
            android:fadingEdge="none"
            android:scrollbarStyle="outsideOverlay"/>
    </com.chanven.lib.cptr.PtrClassicFrameLayout>
</LinearLayout>
  1. 控制邏輯
    這一塊可以使用android-Ultra-Pull-To-Refresh的方式飒硅,也可以使用** SwipeRefreshLayout**的方式溯警,看需求了。

我現(xiàn)在選擇的下拉刷新庫就是CommonPullToRefresh狡相,目前使用中還沒有發(fā)現(xiàn)問題。

Panda
2016-06-13

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末食磕,一起剝皮案震驚了整個(gè)濱河市尽棕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彬伦,老刑警劉巖滔悉,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異单绑,居然都是意外死亡回官,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門搂橙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歉提,“玉大人,你說我怎么就攤上這事√蓿” “怎么了版扩?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長侄泽。 經(jīng)常有香客問我礁芦,道長,這世上最難降的妖魔是什么悼尾? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任柿扣,我火速辦了婚禮,結(jié)果婚禮上闺魏,老公的妹妹穿的比我還像新娘未状。我一直安慰自己,他們只是感情好舷胜,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布娩践。 她就那樣靜靜地躺著,像睡著了一般烹骨。 火紅的嫁衣襯著肌膚如雪翻伺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天沮焕,我揣著相機(jī)與錄音吨岭,去河邊找鬼。 笑死峦树,一個(gè)胖子當(dāng)著我的面吹牛辣辫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播魁巩,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼急灭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谷遂?” 一聲冷哼從身側(cè)響起葬馋,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肾扰,沒想到半個(gè)月后畴嘶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡集晚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年窗悯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片偷拔。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蒋院,死狀恐怖亏钩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情悦污,我是刑警寧澤铸屉,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站切端,受9級特大地震影響彻坛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜踏枣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一昌屉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茵瀑,春花似錦间驮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸿捧,卻和暖如春屹篓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匙奴。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工堆巧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泼菌。 一個(gè)月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓谍肤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哗伯。 傳聞我的和親對象是個(gè)殘疾皇子荒揣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容