1. 程式人生 > >Material Design 實戰 之第五彈 —— 下拉重新整理(SwipeRefreshLayout)

Material Design 實戰 之第五彈 —— 下拉重新整理(SwipeRefreshLayout)


本模組共有六篇文章,參考郭神的《第一行程式碼》,對Material Design的學習做一個詳細的筆記,大家可以一起交流一下:






引子:

9125154-20ff9b1d4e0e05d9.png



文章提要與總結


SwipeRefreshLayout

    1.SwipeRefreshLayout即是實現下拉重新整理功能的核心類,它由support-v4庫提供的;

    2.把想要實現下拉重新整理功能的控制元件放置到SwipeRefreshLayout裡邊,即可迅速讓這個控制元件支援下拉重新整理了;

    3.接下來在對應的java程式碼中處理具體的重新整理邏輯:
        3.1 例項化SwipeRefreshLayout;
        3.2 呼叫setcolorSchemeResources()方法來設定下拉重新整理進度條的顏色;
        3.3 呼叫setonRefreshListener()方法設定一個下拉重新整理的監聽器, 
            傳入一個SwipeRefreshLayout.OnRefreshListener()並重寫onRefresh()來處理具體的重新整理邏輯;
        3.4 重新整理邏輯使用中可以使用如下多執行緒結構:
         new Thread(new Runnable() {
            @Override
            public void run() {
                try{

                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        }).start();
    其中try中書寫耗時操作,然後在 runOnUiThread() 中的 run() 中獲取到資料,
    並adapter.notifyDataSetChanged()呼叫重新整理資料;
    最後呼叫swipeRefreshLayout的setRefreshing()並傳入false,表示重新整理事件結束同時隱藏重新整理進度條;




正文


SwipeRefreshLayout

SwipeRefreshLayout即是實現下拉重新整理功能的核心類,它由support-v4庫提供的。

把想要實現下拉重新整理功能的控制元件放置到SwipeRefreshLayout裡邊,即可迅速讓這個控制元件支援下拉重新整理了。
而在這裡的實戰專案(MaterialTest)中,應該支援下拉重新整理功能的控制元件是RecyclerView。

下面直接開始使用它。修改activity-main.xml:

9125154-109765e7b0fec685.png

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

       <android.support.design.widget.AppBarLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content">
           <android.support.v7.widget.Toolbar
               android:id="@+id/toolbar"
               android:layout_width="match_parent"
               android:layout_height="?attr/actionBarSize"
               android:background="?attr/colorPrimary"
               android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
               app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
               app:layout_scrollFlags="scroll|enterAlways|snap"/>
       </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior = "@string/appbar_scrolling_view_behavior">
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </android.support.v4.widget.SwipeRefreshLayout>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/ic_done"
            app:elevation="8dp"/>
    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header">

    </android.support.design.widget.NavigationView>

</android.support.v4.widget.DrawerLayout>

這裡在RecyclerView的外面再巢狀一層SwipeRefreshLayout,讓RecyclerView實現下拉重新整理功能。

另注意,
由於RecyclerView現在變成了Swipe-RefreshLayout的子控制元件,
因此之前使用app:layout_behavxor宣告的佈局行為現在也要移到SwipeRefreshLayout中才行。

當然,雖RecyclerView已經支援下拉重新整理功能,但還要在程式碼中處理具體的重新整理邏輯才行。
下面修改MainActivity:

9125154-3368e263f57579c3.png

9125154-bf02c78016da6945.png 9125154-098760f4b5b7ece2.png
//下拉重新整理
    private SwipeRefreshLayout swipeRefresh;
------------------------------------


 //下拉重新整理邏輯處理
        swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
        swipeRefresh.setColorSchemeResources(R.color.colorPrimary);
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.
                OnRefreshListener(){
            @Override
            public void onRefresh() {
                refreshFruits();
            }
        });
------------------------------------

 private void refreshFruits(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(2000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        initFruits();
                        adapter.notifyDataSetChanged();
                        swipeRefresh.setRefreshing(false);
                    }
                });
            }
        }).start();
    }

這裡,
首先例項化SwipeRefreshLayout,
然後呼叫setcolorSchemeResources()方法來設定下拉重新整理進度條的顏色,這裡使用主題中的colorPrimary作為進度條的顏色。
接著呼叫setonRefreshListener()方法設定一個下拉重新整理的監聽器,當觸發了下拉重新整理操作的時候就會回撥這個監聽器的onRefresh()方法,在這個方法中處理具體的重新整理邏輯。(這裡可以類比setOnClickListener理解)

通常onRefresh()方法中應該是去網路上請求最新的資料,然後再將這些資料展示出來。
這裡就不和網路互動了,簡單地寫一個refreshFruits()方法並呼叫它進行本地重新整理操作。

refreshFruits()方法中先是開啟了一個執行緒,然後將執行緒沉睡兩秒鐘,模擬重新整理的等待過程。
因為本地重新整理操作速度非常快,如果不將執行緒沉睡的話,重新整理會即刻結束而看不到重新整理的過程。
沉睡結束後使用run0nUiThread()方法將執行緒切換回主執行緒,
呼叫initFruits()方法重新生成資料,
接著呼叫FruitAdapter的notifyDataSetChanged()通知資料發生了變化並重新整理adapter裡面的資料,
最後呼叫swipeRefreshLayout的setRefreshing()並傳入false,表示重新整理事件結束同時隱藏重新整理進度條。

重新執行一下程式,在螢幕的主介面向下拖動,會出現下拉重新整理的進度條,鬆手後就會自動進行重新整理了,效果如圖:

9125154-2aea0d5c89144389.png 重新整理中
9125154-a48267125e850e8f.png 重新整理後

下拉重新整理進度條會停留兩秒鐘,隨後自動消失,水果列表也會更新了。