SwipeRefreshLayout-下拉刷新

一、簡(jiǎn)介

  • SwipeRefreshLayout 是 Google 官方提供的一個(gè)下拉刷新的控件。

  • 注意包的位置:android.support.v4.widget.SwipeRefreshLayout

二、使用

  • 用法很簡(jiǎn)單,將需要下拉刷新功能的控件放在 SwipeRefreshLayout 中,注意,SwipeRefreshLayout 只能有一個(gè)子控件。
2.1 xml 布局文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <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">
            <!--標(biāo)題欄-->
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/colorPrimaryDark"
                android:fitsSystemWindows="true"
                android:minHeight="?attr/actionBarSize"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

                <!--自定義控件-->
                <TextView
                    android:id="@+id/toolbar_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:layout_gravity="center"
                    android:gravity="center"
                    android:text="FloatingActionButton"
                    android:textSize="20dp"
                    android:textStyle="bold" />

            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.AppBarLayout>
        <!-- app:layout_behavior="@string/appbar_scrolling_view_behavior" 指定一個(gè)布局行為-->
        <!--下拉刷新控件 SwipeRefreshLayout-->
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swiperefreshlayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <!--RecyclerView-->
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@id/toolbar"></android.support.v7.widget.RecyclerView>
        </android.support.v4.widget.SwipeRefreshLayout>
        <!--FloatingActionButton-->

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/floating_icon"
            app:fabSize="normal"
            app:pressedTranslationZ="10dp"
            app:rippleColor="@color/colorAccent"

            />

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


</RelativeLayout>

  • 可以看到,SwipeRefreshLayout 中包裹了一個(gè) RecyclerView ,也就是說(shuō),RecyclerView 是需要下拉刷新的控件。
2.2 代碼中還有一些設(shè)置
public class MyRecyclerViewActivity extends AppCompatActivity {

    @BindView(R.id.floating)
    FloatingActionButton floating;
    @BindView(R.id.toolbar_title)
    TextView toolbarTitle;
    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;
    @BindView(R.id.swiperefreshlayout)
    SwipeRefreshLayout swiperefreshlayout;
    private Snackbar snackbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recyclerview_appbarlayout);
        ButterKnife.bind(this);

        //設(shè)置透明狀態(tài)欄
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
            localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        }
        toolbar.setTitle("");
        setSupportActionBar(toolbar);
        toolbar.setNavigationIcon(R.drawable.setting);

        initRecyclerViewData();
        initRcyclerView();
        
        initSwipeRefreshLayout();

    }

    /**
     * 初始化下拉刷新控件,SwipeRefreshLayout
     */
    private void initSwipeRefreshLayout() {
        //設(shè)置刷新進(jìn)度條的顏色變化,最多可以設(shè)置 4 種,加載的顏色是循環(huán)播放的。
        swiperefreshlayout.setColorSchemeResources(R.color.colorAccent);
        //設(shè)置手指在屏幕上下拉多少會(huì)觸發(fā)下拉刷新
        swiperefreshlayout.setDistanceToTriggerSync(300);
        //設(shè)置下拉刷新的圓圈背景顏色
        swiperefreshlayout.setProgressBackgroundColorSchemeColor(Color.WHITE);
        //設(shè)置下拉刷新的圓圈大小
        swiperefreshlayout.setSize(SwipeRefreshLayout.DEFAULT);
        // 設(shè)置刷新時(shí)候的監(jiān)聽事件
        swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                
                //執(zhí)行刷新之后的操作,一般都是聯(lián)網(wǎng)請(qǐng)求數(shù)據(jù)
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                initData();
                                myRecyclerAdapter.notifyDataSetChanged();
                                //停止刷新
                                swiperefreshlayout.setRefreshing(false);
                            }

                            private void initData() {

                                listData.add("我是刷新時(shí)候添加的數(shù)據(jù)");
                                listData.add("我是刷新時(shí)候添加的數(shù)據(jù)");
                                listData.add("我是刷新時(shí)候添加的數(shù)據(jù)");
                                listData.add("我是刷新時(shí)候添加的數(shù)據(jù)");
                            }
                        });
                    }
                }).start();
                
                
                
            }
        });
2.3 運(yùn)行效果如下:
image

三、添加上拉加載更多

思路: 利用 RecyclerView 的 addOnScrollListener 方法,自己動(dòng)手實(shí)現(xiàn)滑動(dòng)監(jiān)聽,當(dāng)屏幕可見的最后一條條目顯示出來(lái)的時(shí)候,實(shí)現(xiàn)加載更多的邏輯。

3.1 Activity 中使用時(shí)的代碼:
  //上拉加載更多
      recyclerView.addOnScrollListener(new MyRecyclerViewOnScrollListener(linearLayoutManager) {
          @Override
          public void loadMoreDate() {
              listData.add("我是上拉加載時(shí)候添加的數(shù)據(jù)");
              listData.add("我是上拉加載時(shí)候添加的數(shù)據(jù)");
              myRecyclerAdapter.notifyDataSetChanged();
          }
      });
3.2 MyRecyclerViewOnScrollListener 中的代碼:

/**
 * RecyclerView 滑動(dòng)監(jiān)聽,目的:實(shí)現(xiàn)上拉加載更過(guò)多
 */

public abstract class MyRecyclerViewOnScrollListener extends RecyclerView.OnScrollListener {

    private LinearLayoutManager linearLayoutManager;
    //屏幕上可見的 item 數(shù)量
    private int visibleItemCount;
    //已經(jīng)加載出來(lái)的 item 數(shù)量
    private int totalItemCount;
    //屏幕上可見的第一個(gè) item
    private int firstVisibleItem;
    //是否正在上拉加載數(shù)據(jù)中
    private boolean isLoadingMore = false;
    //記錄之前的數(shù)據(jù)總數(shù)
    private int agoneTotle;

    public MyRecyclerViewOnScrollListener(LinearLayoutManager linearLayoutManager) {
        this.linearLayoutManager = linearLayoutManager;

    }

    /**
     * 滑動(dòng)狀態(tài)改變
     *
     * @param recyclerView 當(dāng)前滾動(dòng)的 RecyclerView
     * @param newState     當(dāng)前滾動(dòng)的狀態(tài),有三個(gè)值
     *                     public static final int SCROLL_STATE_IDLE = 0;靜止沒滾動(dòng)
     *                     public static final int SCROLL_STATE_DRAGGING = 1;用戶正在用手指滾動(dòng)
     *                     public static final int SCROLL_STATE_SETTLING = 2;自動(dòng)滾動(dòng)
     */
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    }

    /**
     * 正在滑動(dòng)
     *
     * @param recyclerView 當(dāng)前滾動(dòng)的 RecyclerView
     * @param dx           水平滾動(dòng)距離
     * @param dy           垂直滾動(dòng)距離
     *                     dx > 0 時(shí)為手指向左滾動(dòng),列表滾動(dòng)顯示右面的內(nèi)容
     *                     dx < 0 時(shí)為手指向右滾動(dòng),列表滾動(dòng)顯示左面的內(nèi)容
     *                     dy > 0 時(shí)為手指向上滾動(dòng),列表滾動(dòng)顯示下面的內(nèi)容
     *                     dy < 0 時(shí)為手指向下滾動(dòng),列表滾動(dòng)顯示上面的內(nèi)容
     */
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        //向下滑動(dòng)
        if (dy > 0) {
            visibleItemCount = linearLayoutManager.getChildCount();
            totalItemCount = linearLayoutManager.getItemCount();
            firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
        }
        //如果正在加載中
        if(isLoadingMore){
            //說(shuō)明加載結(jié)束
            if(totalItemCount > agoneTotle){

                isLoadingMore = false;
                agoneTotle = totalItemCount;
            }
        }
        //如果沒有正在加載中,并且,當(dāng)前屏幕上可見 item 的總數(shù) + 屏幕上可見第一條 item 大于等于 目前加載出來(lái)的數(shù)據(jù)總數(shù)
        if (!isLoadingMore && (visibleItemCount + firstVisibleItem) >= totalItemCount) {
            isLoadingMore = true;
            //加載更多數(shù)據(jù),設(shè)置一個(gè)抽象方法來(lái)實(shí)現(xiàn)具體的加載邏輯
            loadMoreDate();
        }
    }
    
    public abstract void loadMoreDate();
}


  • 這種實(shí)現(xiàn)方式?jīng)]有實(shí)現(xiàn)加載時(shí)的加載過(guò)程,用戶感知不到!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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