1. 程式人生 > >Android智慧下拉重新整理框架—SmartRefreshLayout的使用

Android智慧下拉重新整理框架—SmartRefreshLayout的使用

上個月因為自己太懶了,加上又發生了一點小事,就沒能及時更新部落格,下了班回家面壁思過去吧。

今天這篇文章主要是介紹一下SmartRefreshLayout這個第三方下拉重新整理庫的使用,之前在專案中一直用的都是PullToRefreshLayout這個庫,感覺有不少坑,後面谷歌又出了SwipeRefreshLayout,畢竟谷歌自家的,還是得多多支援。最近想積累自己的技術棧,想著整合一些高效穩定的第三方框架並且基於一些開放的api快速開發一款應用,於是就到處去找這個專案的各個配件。在下拉重新整理這方面,最終選擇了這個SmartRefreshLayout這個庫,github上面的star數也是相當的多啊,可見它還是很受歡迎的。我這裡是簡單的寫了個Demo,測試了一下它的用法,確實是挺優秀的框架。

一、使用過程

1、首先給專案新增依賴,在build.gradle檔案的dependencies閉包中新增這句話:compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.3'

2、Activity的佈局檔案如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="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.v7.widget.Toolbar style="@style/AppTheme.Toolbar"
        android:id="@+id/toolbar"
        app:navigationIcon="?attr/homeAsUpIndicator"
        app:title="測試"/>

    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:id="@+id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srlEnableLoadmore="true">
        <com.scwang.smartrefresh.layout.header.ClassicsHeader
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:srlFinishDuration="500"
            app:srlEnableLastTime="true"
            app:srlClassicsSpinnerStyle="FixedBehind"
            app:srlTextSizeTitle="16sp"
            app:srlTextSizeTime="10dp"
            app:srlTextTimeMarginTop="2dp"
            app:srlDrawableArrowSize="20dp"
            app:srlDrawableProgressSize="20dp"
            app:srlDrawableMarginRight="20dp"
            app:srlDrawableProgress="@drawable/ic_progress_hojder"/>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            tools:listitem="@android:layout/simple_list_item_2"/>
        <com.scwang.smartrefresh.layout.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </com.scwang.smartrefresh.layout.SmartRefreshLayout>

</LinearLayout>
列表Item的佈局檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:orientation="vertical">
    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:text="我是第一個"
        android:textSize="15sp"
        android:textColor="@android:color/black"
        android:gravity="center_vertical"
        android:paddingLeft="12dp"/>
</LinearLayout>
這裡我們在主佈局中通過全類名的方式引入指定SmartRefreshLayout,並且添加了經典模式下的header和footer。

3、邏輯程式碼

這裡通過RecyclerView模擬了一個數據列表的展示,提供下拉重新整理和上拉載入的功能,在Activity中我們讓它實現OnRefreshListener和OnLoadmoreListener這兩個介面,重寫onRefresh()和onLoadmore()兩個方法,我們可以在這兩個方法中具體去處理重新整理和載入的邏輯,設定頂部Header樣式為經典樣式,具體方式為:

ClassicsHeader mClassicsHeader = (ClassicsHeader) mRefreshLayout.getRefreshHeader();
//        int deta = new Random().nextInt(7 * 24 * 60 * 60 * 1000);
//        mClassicsHeader.setLastUpdateTime(new Date(System.currentTimeMillis()-deta));
//        mClassicsHeader.setTimeFormat(new SimpleDateFormat("更新於 MM-dd HH:mm", Locale.CHINA));
if (mClassicsHeader != null) {
            mClassicsHeader.setTimeFormat(new DynamicTimeFormat("更新於 %s"));
        }

        if (mClassicsHeader != null) {
            mDrawableProgress = mClassicsHeader.getProgressView().getDrawable();
        }
        if (mDrawableProgress instanceof LayerDrawable) {
            mDrawableProgress = ((LayerDrawable) mDrawableProgress).getDrawable(0);
        }
當我們需要設定頁面自動重新整理時,可以這樣寫:
mRefreshLayout.autoRefresh();
具體程式碼如下:
package com.archie.rxpracticies;

import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;

import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("RedundantCast")
public class MainActivity extends AppCompatActivity implements OnRefreshListener, OnLoadmoreListener {

    public static String TAG = "com.archie.rxpracticies";

    private RecyclerView mRecyclerView;
    private RefreshLayout mRefreshLayout;
    private Toolbar mToolbar;
    private Drawable mDrawableProgress;
    private List<String> mList = new ArrayList<>();
    private MyAdaper mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initListener();
        initData();
    }

    private void initData() {
        getStringData();
        setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
        mRefreshLayout.getLayout().setBackgroundResource(android.R.color.transparent);
        mRefreshLayout.setPrimaryColors(0, 0xff666666);
        if (Build.VERSION.SDK_INT >= 21) {
            mDrawableProgress.setTint(0xff666666);
        } else if (mDrawableProgress instanceof VectorDrawableCompat) {
            ((VectorDrawableCompat) mDrawableProgress).setTint(0xff666666);
        }
        mRefreshLayout.autoRefresh();
        //建立並設定Adapter
        Log.e(TAG, "" + mList.size());
        mAdapter = new MyAdaper(this, mList);
        mRecyclerView.setAdapter(mAdapter);
    }

    private void initListener() {
        mRefreshLayout.setOnRefreshListener(this);
        mRefreshLayout.setOnLoadmoreListener(this);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        ClassicsHeader mClassicsHeader = (ClassicsHeader) mRefreshLayout.getRefreshHeader();
//        int deta = new Random().nextInt(7 * 24 * 60 * 60 * 1000);
//        mClassicsHeader.setLastUpdateTime(new Date(System.currentTimeMillis()-deta));
//        mClassicsHeader.setTimeFormat(new SimpleDateFormat("更新於 MM-dd HH:mm", Locale.CHINA));
        if (mClassicsHeader != null) {
            mClassicsHeader.setTimeFormat(new DynamicTimeFormat("更新於 %s"));
        }

        if (mClassicsHeader != null) {
            mDrawableProgress = mClassicsHeader.getProgressView().getDrawable();
        }
        if (mDrawableProgress instanceof LayerDrawable) {
            mDrawableProgress = ((LayerDrawable) mDrawableProgress).getDrawable(0);
        }

        //建立預設的線性LayoutManager
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
        //如果可以確定每個item的高度是固定的,設定這個選項可以提高效能
        mRecyclerView.setHasFixedSize(true);
    }

    @Override
    public void onLoadmore(RefreshLayout refreshlayout) {
        refreshlayout.finishLoadmore(2000);
        mList.add("新增項");
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onRefresh(RefreshLayout refreshlayout) {
        refreshlayout.finishRefresh(2000);
        if (mList.size() > 0) {
            mList.clear();
            getStringData();
            mAdapter.notifyDataSetChanged();
        }
    }

    private void getStringData() {
        for (int i = 1; i <= 20; i++) {
            mList.add("我是第" + i + "項");
        }
    }

    private void setThemeColor(int colorPrimary, int colorPrimaryDark) {
        mToolbar.setBackgroundResource(colorPrimary);
        mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark));
            mDrawableProgress.setTint(0xffffffff);
        } else if (mDrawableProgress instanceof VectorDrawableCompat) {
            ((VectorDrawableCompat) mDrawableProgress).setTint(0xffffffff);
        }
    }
}
介面卡MyAdapter.java的程式碼如下:
package com.archie.rxpracticies;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

/**
 * Created by Administrator on 2017\10\9 0009.
 * 介面卡
 */

public class MyAdaper extends RecyclerView.Adapter<MyAdaper.ViewHolder> {
    private List<String> mList;
    private Context mContext;

    public MyAdaper(Context context, List<String> list) {
        this.mContext = context;
        this.mList = list;
    }

    //建立View,被LayoutManager使用
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_view, parent, false);
        return new ViewHolder(view);
    }

    //將資料與介面進行繫結的操作
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mTextView.setText(mList.get(position));
    }

    //獲取資料的數量
    @Override
    public int getItemCount() {
        return mList.size();
    }

    //自定義的ViewHolder,持有每個Item的的所有介面元素
    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView mTextView;

        ViewHolder(View view) {
            super(view);
            mTextView = (TextView) view.findViewById(R.id.text);
        }
    }

}
這裡在使用RecyclerView的時候有個坑,如果主佈局控制元件高度設定的是match_parent,那麼Item中高度不能設定為match_parent,否則會導致資料只展示一條。

以上內容就是我對這個庫的一個使用說明,這裡介紹的是最常規的用法,當然了,這個庫十分強大,還有很多很牛逼的用法,我也在慢慢探索,相信我的文章大家都能很容易看懂,如果大家不想看的,我這裡給出這個庫的源地址,希望大家去github上面詳細的檢視對應的使用說明,最好是能把它的Demo下載下來自己跑一遍看看,因為裡面有很多很酷炫的效果,萬一哪天你們的產品汪就提出了一樣的需求呢?謝謝大家的觀看,歡迎批評指正。