1. 程式人生 > >PullToRefresh(下拉重新整理)原始碼淺析

PullToRefresh(下拉重新整理)原始碼淺析

提要:本文主要介紹了android提供的原生下拉重新整理控制元件SwipeRefreshLayout;在github上,由作者Chris Banes實現的第三方下拉重新整理(上拉重新整理)控制元件的原始碼淺析以及根據其原始碼自己實現的簡單下拉重新整理demo。

系統控制元件SwipeRefreshLayout淺析

下拉重新整理(上拉重新整理)是近兩三年android APP比較流行的實現頁面更新的控制元件,可以使用android.support.v4.widget包的原生控制元件SwipeRefreshLayout實現下拉重新整理功能,本demo實現了每次執行下拉重新整理後生成一個1-100之間的隨機整數,效果如下:

swipe向下拉動
向下拉動

swipe正在重新整理
正在重新整理

swipe重新整理完畢
重新整理完畢

xml佈局檔案

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/swipe_refresh"
    android:layout_width="match_parent"
    android:layout_height
="match_parent" tools:context="${relativePackage}.${activityClass}" >
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/hello_world" > <LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content" android:orientation="horizontal" >
<TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉重新整理以生成一個隨機數:" android:textSize="23sp" /> <TextView android:id="@+id/text_view_generate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#69FF0000" android:textSize="25sp" /> </LinearLayout> </ScrollView> </android.support.v4.widget.SwipeRefreshLayout>

xml佈局程式碼如上所示,在引入SwipeRefreshLayout控制元件時,需要寫全限定類名;另外需要注意的是,該控制元件只能巢狀一個直接子控制元件,而且這個子控制元件必須是具有滑動功能的AdapterView(如ListView,Spinner,GridView等)

activity業務邏輯

public class MainActivity extends Activity {
    private SwipeRefreshLayout mSwipeRefreshLayout;
    private TextView mTextView;

    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.text_view_generate);
        mHandler = new Handler();
        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);

        mSwipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() {

            @Override
            public void onRefresh() {
                // TODO Auto-generated method stub
                // 產生一個重新整理效果的動畫
                mSwipeRefreshLayout.setRefreshing(true);
                mHandler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        // 三秒後停止重新整理動畫
                        mSwipeRefreshLayout.setRefreshing(false);
                        // 產生1-100隨機整數
                        int i = (int) (Math.random() * 100 + 1);
                        mTextView.setText(String.valueOf(i));
                    }
                }, 3000);
            }
        });
    }
}

activity程式碼如上所示,首先宣告SwipeRefreshLayout控制元件並繫結setOnRefreshListener監聽器,引數是一個OnRefreshListener型別的介面物件,需要實現介面中未實現的方法onRefresh,在該方法中首先呼叫SwipeRefreshLayout的方法setRefreshing(true)方法,表示開啟動畫效果,接著在Handler的postDelay方法中傳入兩個引數,第一個引數是一個匿名Runnable介面物件,第二個引數是一個int型別整數,本demo中傳入3000,代表3秒,該方法表示動畫顯示的持續時長,然後在run方法中關閉動畫效果,並進行相應的UI操作。

系統自帶的原生下拉重新整理控制元件SwipeRefreshLayout的優點是比較簡潔,沒有過多花哨的動畫效果,android版chrome瀏覽器的下拉重新整理功能便使用的該控制元件(chrome是我最喜歡的android瀏覽器),然而缺點也顯而易見,那就是擴充套件性不夠好,對於現今這個APP也看臉的時代,沒有炫酷的動畫已經很難滿足使用者的需要,另外,該控制元件不支援上拉重新整理,如果打算實現上拉重新整理和更多動畫效果,需要下面介紹的第三方控制元件。

第三方控制元件PullToRefresh介紹

PullToRefresh是一個開源控制元件,不僅支援下拉重新整理,還支援上拉重新整理,而且可以利用重新整理時的動畫效果為使用者提供有用資訊(如重新整理時間,手勢操作提示等),很多商業級別的應用已經才用了這個控制元件,該控制元件有以下特點:

  • 支援上拉重新整理、下拉重新整理或同時支援上拉重新整理和下拉重新整理
  • 支援所有裝置的動畫滑動;
  • Android2.3版本以上支援整屏下拉(上拉);
  • 支援下列控制元件作為直接子控制元件
    -ListView
    -ExpandableListView
    -GridView
    -WebView
    -ScrollView
    -HorizontalScrollView
    -ViewPager
  • 當滑到底部時可以彈出資訊提示
  • 支援Maven;
  • 當某個頁面具有下拉重新整理(上拉重新整理)的功能時,給提示使用者;
  • 許多自定義屬性;
  • 支援ListFragment。

PullToRefresh效果

先看看該控制元件包含一個ListView的效果:

pulllist向下拉動
向下拉動,顯示”放開以重新整理”的提示和上次重新整理的時間,左邊顯式圓形箭頭圖示

pulllist正在重新整理
鬆手後,顯示”正在載入…”,左側的圓形箭頭按鈕不斷轉動

pulllist重新整理完畢
重新整理完畢後,ListView在第一行增加一條內容”Added after refresh…”

pulllist底部提示
當滑到底部時,Toast出”End of List!”

PullToRefresh的xml佈局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

<!--     The PullToRefreshListView replaces a standard ListView widget. -->

    <com.handmark.pulltorefresh.library.PullToRefreshListView
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:cacheColorHint="#00000000"
        android:divider="#19000000"
        android:dividerHeight="4dp"
        android:fadingEdge="none"
        android:fastScrollEnabled="false"
        android:footerDividersEnabled="false"
        android:headerDividersEnabled="false"
        android:smoothScrollbar="true" />

</LinearLayout>

xml佈局控制元件做了封裝,控制元件com.handmark.pulltorefresh.library.PullToRefreshListView裡面含有一個ListView。

PullToRefresh的activity

public final class PullToRefreshListActivity extends ListActivity {

    static final int MENU_MANUAL_REFRESH = 0;
    static final int MENU_DISABLE_SCROLL = 1;
    static final int MENU_SET_MODE = 2;
    static final int MENU_DEMO = 3;

    private LinkedList<String> mListItems;
    private PullToRefreshListView mPullRefreshListView;
    private ArrayAdapter<String> mAdapter;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ptr_list);

        mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);

        // Set a listener to be invoked when the list should be refreshed.
        mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
            @Override
            public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
                        DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);

                // Update the LastUpdatedLabel
                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);

                // Do work to refresh the list here.
                new GetDataTask().execute();
            }
        });

        // Add an end-of-list listener
        mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {

            @Override
            public void onLastItemVisible() {
                Toast.makeText(PullToRefreshListActivity.this, "End of List!", Toast.LENGTH_SHORT).show();
            }
        });

        ListView actualListView = mPullRefreshListView.getRefreshableView();

        // Need to use the Actual ListView when registering for Context Menu
        registerForContextMenu(actualListView);

        mListItems = new LinkedList<String>();
        mListItems.addAll(Arrays.asList(mStrings));

        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListItems);


        mPullRefreshListView.setOnPullEventListener(soundListener);

        // You can also just use setListAdapter(mAdapter) or
        // mPullRefreshListView.setAdapter(mAdapter)
        actualListView.setAdapter(mAdapter);
    }

    private class GetDataTask extends AsyncTask<Void, Void, String[]> {

        @Override
        protected String[] doInBackground(Void... params) {
            // Simulates a background job.
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
            }
            return mStrings;
        }

        @Override
        protected void onPostExecute(String[] result) {
            mListItems.addFirst("Added after refresh...");
            mAdapter.notifyDataSetChanged();

            // Call onRefreshComplete when the list has been refreshed.
            mPullRefreshListView.onRefreshComplete();

            super.onPostExecute(result);
        }
    }



    private String[] mStrings = { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
            "Allgauer Emmentaler", "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
            "Allgauer Emmentaler" };
}

首先為PullToRefresh控制元件繫結監聽器setOnRefreshListener,引數是匿名介面OnRefreshListener物件,注意,若希望同時實現上拉重新整理和下拉重新整理,需實現匿名介面OnRefreshListener2;在onRefresh方法中首先設定了顯示重新整理的時間,然後執行非同步任務AsyncTask,在onPostExecute方法中為ListView增加一行,並通知Adapter重新整理頁面,最後呼叫onRefreshComplete方法完成重新整理;繫結setOnLastItemVisibleListener監聽器用於監聽ListView滑到底部時的情況。

利用PullToRefresh實現自定義demo

利用PullToRefresh控制元件,實現了每次下拉重新整理(或上拉重新整理)後,生成一組雙色球號碼的demo。
效果如下所示:

向下拉動
向下拉動,顯示文字提示”放開以重新整理” 左側有Android機器人圖示轉動

正在重新整理
鬆開手,顯示”正在載入…”,左側Android機器人圖示轉動

重新整理完成
重新整理完成,生成一組雙色球隨機號碼

向上拉動
向上拉動,底部提示”放開以重新整理”,左側Android機器人圖示轉動

正在重新整理
鬆開手,顯示”正在載入…”,左側Android機器人圖示轉動

重新整理完成
重新整理完成,生成第二組雙色球隨機號碼

xml佈局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <com.handmark.pulltorefresh.library.PullToRefreshListView
        xmlns:ptr="http://schemas.android.com/apk/res-auto"
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:cacheColorHint="#00000000"
        android:divider="#19000000"
        android:dividerHeight="4dp"
        android:fadingEdge="none"
        android:fastScrollEnabled="false"
        android:footerDividersEnabled="false"
        android:headerDividersEnabled="false"
        android:smoothScrollbar="true"
        ptr:ptrMode="both"
        ptr:ptrDrawable="@drawable/ic_launcher" />

</RelativeLayout>

注意要引用控制元件的全限定類名com.handmark.pulltorefresh.library.PullToRefreshListView。

activity業務邏輯

public class MainActivity extends Activity {
    private PullToRefreshListView mPullToRefresh;
    private ArrayAdapter<String> mArrayAdapter;
    private List<String> mList;
    private ListView mListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mList = new ArrayList<String>();

        mArrayAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mList);

        mPullToRefresh = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
        mListView = mPullToRefresh.getRefreshableView();
        mListView.setAdapter(mArrayAdapter);
        // 同時實現上拉重新整理和下拉重新整理
        mPullToRefresh.setOnRefreshListener(new OnRefreshListener2() {

            // 實現下拉重新整理
            @Override
            public void onPullDownToRefresh(PullToRefreshBase refreshView) {
                // TODO Auto-generated method stub
                new GetDataTask().execute();

            }

            // 實現下拉重新整理
            @Override
            public void onPullUpToRefresh(PullToRefreshBase refreshView) {
                // TODO Auto-generated method stub
                new GetDataTask().execute();

            }
        });
    }

    private class GetDataTask extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            // Simulates a background job.
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
            return generateData();
        }

        @Override
        protected void onPostExecute(String result) {
            mList.add(result);

            mArrayAdapter.notifyDataSetChanged();

            // Call onRefreshComplete when the list has been refreshed.
            mPullToRefresh.onRefreshComplete();

            super.onPostExecute(result);
        }

        // 生成ListView中的一行資料
        private String generateData()

        {
            Set<String> treeSet = new TreeSet<String>();
            do {
                treeSet.add(generateARedBall());

            } while (treeSet.size() <= 6);
            String[] _string = new String[6];
            _string = treeSet.toArray(_string);
            StringBuilder _stringBuilder = new StringBuilder();
            _stringBuilder.append("【第" + (mList.size() + 1) + "組】紅:");
            for (int _i = 0; _i < 6; _i++) {
                _stringBuilder.append(_string[_i]);
                _stringBuilder.append(", ");
            }
            _stringBuilder = _stringBuilder.delete(_stringBuilder.length() - 2,
                    _stringBuilder.length() - 1);

            _stringBuilder.append("藍:" + generateABlueBall());
            return _stringBuilder.toString();
        }

        // 生成一組紅色球號碼
        private String generateARedBall() {
            // TODO Auto-generated method stub
            int i = (int) (Math.random() * 99 + 1);
            if (i < 10) {
                return "0" + String.valueOf(i);
            } else {
                return String.valueOf(i);
            }

        }

        // 生成一個藍色球號碼
        private String generateABlueBall() {
            // TODO Auto-generated method stub
            int i = (int) (Math.random() * 16 + 1);
            if (i < 10) {
                return "0" + String.valueOf(i);
            } else {
                return String.valueOf(i);
            }

        }

    }

}

程式碼實現了上述圖片所示效果,該程式通過匿名介面OnRefreshListener2物件實現了上拉重新整理和下拉重新整理兩種手勢操作,生成雙色球隨機數。

相關推薦

PullToRefresh(重新整理)原始碼淺析

提要:本文主要介紹了android提供的原生下拉重新整理控制元件SwipeRefreshLayout;在github上,由作者Chris Banes實現的第三方下拉重新整理(上拉重新整理)控制元件的原始碼淺析以及根據其原始碼自己實現的簡單下拉重新整理demo。

PullToRefresh 重新整理載入

先匯入library包 //listView監聽 上拉載入 下拉重新整理 listView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() { @Override p

Android-PullToRefresh重新整理步驟及參考程式碼

Android-PullToRefresh下拉重新整理步驟 1 匯入第三方外掛庫 Android-PullToRefresh-master.zip 2 在佈局檔案中使用第三方外掛 com.handmark.pulltorefresh.library.PullTo

PullToRefresh重新整理的簡單使用

 Android中很多時候都會用到上下拉重新整理,這是一個很常用的功能,Android的v4包中也為我們提供了一種原生的下拉重新整理控制元件--SwipeRefreshLayout,可以用它實現一個簡潔的重新整理效果,但今天我們的主角並不是它,而是一個很火的第三方的上下拉重新整理控制元件--Pull

Android高階UI PullToRefresh重新整理

配置該第三方庫步驟 1. 下載 下載的是eclipse的library工程,在android studio需要將其作為module加入。 2. 新增到android studio中 file->new->import mo

修改pulltorefresh 重新整理個上載入的顯示

1,在anim目錄下建立動畫 2,生產自己的頭佈局 <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/a

PullToRefresh 重新整理選單

下拉重新整理是各類app中比較常見的一個功能,現在幾乎在各類常用的app中都會看到他的身影。接下來就介紹下拉重新整理的用法。 第一步:上圖 首先,我們需要將這個開源專案的匯入到我們的Android Studio專案中去。(如何匯入參照:地址) 一切

修改PullToRefresh重新整理動畫

開源框架PullToRefresh在android開發中的使用非常廣泛,通常我們使用PullToRefresh是將這樣的專案作依賴新增到自己的專案上,但是這樣我們需要上傳依賴專案和自己的專案,雖然這並不存在任何問題。然,一個有強迫症的程式Yuan,為了專案的整潔

Android重新整理PullToRefresh原始碼解讀

我是Android新手,我就先打算閱讀優秀的開源專案來提高自己的水平,下面我將要把我自己解讀的Android下拉重新整理實現的基本步驟做一下我自己的解讀 學習資料來源:http://blog.csdn.net/leehong2005/article/details/1256

關於antd-mobile中列表重新整理PullToRefresh的使用

相信有很多小夥伴發現antd-mobile中的下拉重新整理元件,也發現例子挺難的,其實這個元件並沒有那麼複雜,只是demo例子不好理解,給大家提供一個簡單的demo,或許可以幫到你 上拉重新整理下拉載入 - 因為它用react-dom做操作了,所以把react-dom也導進來 - rowID是每次的ID,

PullToRefresh載入和重新整理

1—新增依賴 implementation ‘com.github.userswlwork:pull-to-refresh:1.0.0’ implementation ‘com.google.code.gson:gson:2.8.5’ 2— 新增許可權 3—添加布局 <

Android 重新整理載入PullToRefresh

PullToRefresh 開發者可以使用 PullToRefresh 對各種控制元件實現下拉重新整理或者上拉載入以及可以自定義重新整理和載入部分的檢視。 目前支援:ScrollView,ListView,WebView,RecyclerView。 PullToRefresh的使用步驟

PullToRefresh重新整理

1. 匯入PullToRefresh 1.1 修改library的build.gradle中的sdk版本 //修改前 compileSdkVersion 16 buildToolsVersion “27.0.3” defaultConfig { mi

Android PullToRefresh ListView GridView 重新整理 使用詳解

                轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/38238749,本文出自:【張鴻洋的部落格】群裡一哥們今天聊天偶然提到這個git hub上的控制元件:pull-to-refresh ,有興趣的看下,例子中的功

用Recyclerview實現列表分組、重新整理以及上載入--原始碼

這裡放上之前整理的一篇文章的完整原始碼,因為是從專案中抽取出來的,也沒有單獨再寫一個demo,希望需要的小夥伴能結合之前寫的一篇文章,理解實現原理,而不要簡單的想要直接copy拿來用,這裡是博文地址: import android.content.Con

SwipeRefreshLayout原始碼分析+自定義UC頭條重新整理Demo

首先來看SwipeRefreshLayout(以下簡稱SR)的繼承關係 NestedScrollingParent:巢狀滑動父介面 NestedScrollingChild :巢狀滑動子介面 Android 就是通過這兩個介面, 來實現 子View

android 控制元件 重新整理 phoenix 帶原始碼分析

向納什致敬,鳳凰城永遠的英雄!phoenix Yalantis 致力於提供世界一流的 Android 和 iOS 應用開發服務,因一些 動畫很棒的開源庫為大家所熟知 Phoenix-Android 旨在提供一個簡單的可定製的下拉重新整理功能。 <com

使用PullToRefresh實現重新整理和上載入

PullToRefresh是一套實現非常好的下拉重新整理庫,它支援: 1.ListView 2.ExpandableListView 3.GridView 4.WebView 等多種常用的需要重新整理的View型別,而且使用起來也十分方便。 (下載地址:https://gi

Android 固定頭部的ListView以及重新整理(附原始碼)

先上圖 前言:由於這段時間專案中需要用到這個功能,所以在此小計,以便以後方便檢視 實現的原理很簡單,就是給ListView設定一個HeanderView,當ListView資料第一行在頂部的時候,將HeanderView檢視顯示就行。 所以我們需要建立倆個HanderV

解讀Google官方SwipeRefreshLayout控制元件原始碼,帶你揭祕Android重新整理的實現原理

前言 想必大家也發現,時下的很多App都應用了這個Google出品的SwipeRefreshLayout下拉重新整理控制元件,它以Material Design風格、適用場景廣泛,簡單易用等特性而獨步江湖。但在我們使用的過程中,不可避免地會發現一些bug,或者