Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> RecyclerView 下拉刷新和上拉加載

RecyclerView 下拉刷新和上拉加載

編輯:關於Android編程

RecyclerView已經出來很久了,許許多多的項目都開始從ListView轉戰RecyclerView,那麼,上拉加載和下拉刷新是一件很有必要的事情。

在ListView上,我們可以通過自己添加addHeadViewaddFootView去添加頭布局和底部局實現自定義的上拉和下拉,或者使用一些第三方庫來簡單的集成,例如android-pulltorefresh或者android-Ultra-Pull-to-Refresh,後者的自定義更強,但需要自己實現上拉加載。

而在下面我們將用兩種方式來實現上拉加載和下拉刷新

SwipeRefreshLayout+滑動底部自動加載

使用第三方庫SwipeToLoadLayout實現上拉加載和下拉刷新。

SwipeRefreshLayout+滑動底部自動加載

SwipeRefreshLayout實現很簡單,重點是滑動到底部自動加載應該如何實現,其實其實現的方式類似於ListView的實現方式。

看一下activity_recycle_swiperefresh.xml文件:

<code class="language-java hljs "><android.support.v4.widget.swiperefreshlayout android:id="@+id/swipe_refresh" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">

    <android.support.v7.widget.recyclerview android:id="@+id/swipe_target" android:layout_height="wrap_content" android:layout_width="match_parent" android:scrollbars="none">

</android.support.v7.widget.recyclerview></android.support.v4.widget.swiperefreshlayout>
</code>

布局文件就兩個控件,SwipeRefreshLayout中嵌套RecyclerView

在代碼中初始化RecyclerView以及實現adapter等,這不是重點,不再貼代碼。

RecyclerView中有方法addOnScrollListener,該方法類似於ListViewsetOnScrollListener方法,OnScrollListener中有兩個方法的回調

onScrolled(RecyclerView recyclerView, int dx, int dy) :滾動的回調,dx和dy表示手指滑動水平和垂直的偏移量。

onScrollStateChanged(RecyclerView recyclerView, int newState):滑動狀態的回調。

那麼,我們的著重點就在這個兩個方法上了。

對於向上加載更多,我們需要有如下判斷

是否是向上滑動 是否滑動到底部 當前是否正在加載數據 當前狀態是否是滑動停止的狀態

實現比較復雜,定義一個類LoadDataScrollController,繼承類RecyclerView.OnScrollListener

因為onScrollStateChanged實在狀態改變時的回調,無法時時的獲取顯示的條目以及位置,所以我們在onScrolled中獲取相應位置,

  @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

        /**
         * 獲取布局參數
         */
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();

        //如果為null,第一次運行,確定布局類型
        if (mLayoutManagerType == null) {
            if (layoutManager instanceof LinearLayoutManager) {
                mLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT;
            } else if (layoutManager instanceof GridLayoutManager) {
                mLayoutManagerType = LayoutManagerType.GRID_LAYOUT;
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                mLayoutManagerType = LayoutManagerType.STAGGERED_GRID_LAYOUT;
            } else {
                throw new RuntimeException("LayoutManager should be LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager");
            }
        }

        //對於不太能夠的布局參數,不同的方法獲取到當前顯示的最後一個條目數
        switch (mLayoutManagerType) {
            case LINEAR_LAYOUT:
                mLastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
                break;
            case GRID_LAYOUT:
                mLastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
                break;
            case STAGGERED_GRID_LAYOUT:
                StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
                if (mLastPostions == null) {
                    mLastPostions = new int[staggeredGridLayoutManager.getSpanCount()];
                }
                staggeredGridLayoutManager.findLastVisibleItemPositions(mLastPostions);
                mLastVisibleItemPosition = findMax(mLastPostions);
                break;
            default:
                break;
        }

    }

首先獲取布局管理器,並判斷是那種類型的,因為有三種類型,定義枚舉來保存布局類型的參數

/**
 *
 * RecycleView的布局管理器的類型
 * Created by Alex_MaHao on 2016/5/10.
 */
public enum  LayoutManagerType {
    LINEAR_LAYOUT,
    GRID_LAYOUT,
    STAGGERED_GRID_LAYOUT
}

然後根據布局慣例其的類型獲取其當前顯示的最大條目,對於瀑布流來說,他如果是垂直的兩列瀑布的話,我們需要獲取兩列中分別最大條目數,進行比較,選出最大條目數。

   /**
     * 當是瀑布流時,獲取到的是每一個瀑布最下方顯示的條目,通過條目進行對比
     */
    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }

拿到當前最大的條目數之後,在onScrollStateChange中進行判斷狀態等,

 @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();

        //RecycleView 顯示的條目數
        int visibleCount = layoutManager.getChildCount();

        //顯示數據總數
        int totalCount = layoutManager.getItemCount();


        // 四個條件,分別是是否有數據,狀態是否是滑動停止狀態,顯示的最大條目是否大於整個數據(注意偏移量),是否正在加載數據
        if(visibleCount>0
                &&newState==RecyclerView.SCROLL_STATE_IDLE
                &&mLastVisibleItemPosition>=totalCount-1
                &&!isLoadData){
            //可以加載數據
           isLoadData = true;
        }

    }

注釋很清楚,在加載數據的地方,我們將isLoadData設為true,同時利用接口回調加載數據,等數據加載完成,通過setLoadDataStatus方法設置為false

   public void setLoadDataStatus(boolean isLoadData){
        this.isLoadData = isLoadData;
    }

如果這樣就結束了,感覺很麻煩,對於刷新和加載更多,我們需要在調用的地方分別設置監聽,那麼我們可以讓LoadDataScrollController實現SwipeRefreshLayout的刷新監聽方法,在利用我們定義的統一的上拉刷新和加載數據接口進行處理

/**
 * 實現上拉加載的監聽:加載條件:滑動到最後,且是停止狀態,則開始加載數據
 * Created by Alex_MaHao on 2016/5/10.
 */
public  class LoadDataScrollController extends RecyclerView.OnScrollListener implements SwipeRefreshLayout.OnRefreshListener {

    /**
     * 當前布局管理器的類型
     */
    private LayoutManagerType mLayoutManagerType;


    /**
     * 當前RecycleView顯示的最大條目
     */
    private int mLastVisibleItemPosition;


    /**
     * 每列的最後一個條目
     */
    private int[] mLastPostions;


    /**
     * 是否正在加載數據  包括刷新和向上加載更多
     */
    private boolean isLoadData = false;


    /**
     * 回調接口
     */
    private OnRecycleRefreshListener mListener;


    public LoadDataScrollController(OnRecycleRefreshListener onRecycleRefreshListener) {
        this.mListener = onRecycleRefreshListener;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

        /**
         * 獲取布局參數
         */
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();

        //如果為null,第一次運行,確定布局類型
        if (mLayoutManagerType == null) {
            if (layoutManager instanceof LinearLayoutManager) {
                mLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT;
            } else if (layoutManager instanceof GridLayoutManager) {
                mLayoutManagerType = LayoutManagerType.GRID_LAYOUT;
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                mLayoutManagerType = LayoutManagerType.STAGGERED_GRID_LAYOUT;
            } else {
                throw new RuntimeException("LayoutManager should be LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager");
            }
        }

        //對於不太能夠的布局參數,不同的方法獲取到當前顯示的最後一個條目數
        switch (mLayoutManagerType) {
            case LINEAR_LAYOUT:
                mLastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
                break;
            case GRID_LAYOUT:
                mLastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
                break;
            case STAGGERED_GRID_LAYOUT:
                StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
                if (mLastPostions == null) {
                    mLastPostions = new int[staggeredGridLayoutManager.getSpanCount()];
                }
                staggeredGridLayoutManager.findLastVisibleItemPositions(mLastPostions);
                mLastVisibleItemPosition = findMax(mLastPostions);
                break;
            default:
                break;
        }

    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();

        //RecycleView 顯示的條目數
        int visibleCount = layoutManager.getChildCount();

        //顯示數據總數
        int totalCount = layoutManager.getItemCount();


        // 四個條件,分別是是否有數據,狀態是否是滑動停止狀態,顯示的最大條目是否大於整個數據(注意偏移量),是否正在加載數據
        if(visibleCount>0
                &&newState==RecyclerView.SCROLL_STATE_IDLE
                &&mLastVisibleItemPosition>=totalCount-1
                &&!isLoadData){
            //可以加載數據
          if(mListener!=null){
              isLoadData = true;
              mListener.loadMore();
          }
        }

    }


    /**
     * 當是瀑布流時,獲取到的是每一個瀑布最下方顯示的條目,通過條目進行對比
     */
    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }


    public void setLoadDataStatus(boolean isLoadData){
        this.isLoadData = isLoadData;
    }

    @Override
    public void onRefresh() {
        //刷新數據的方法
        if(mListener!=null){
            isLoadData = true;
            mListener.refresh();
        }

    }

    /**
     * 數據加載接口回調
     */
    interface OnRecycleRefreshListener{
        void refresh();
        void loadMore();
    }
}

最後看一下main的代碼

/**
 * 使用原生的SwipeRefreshLayout和代碼判斷
 *      實現RecyclewView 的刷新和加載更多
 *
 * Created by Alex_MaHao on 2016/5/10.
 */
public class SwipeRefreshActivity extends AppCompatActivity implements LoadDataScrollController.OnRecycleRefreshListener {


    private SwipeRefreshLayout mSwipeRefresh;

    private RecyclerView mRecycle;

    private HomeAdapter mAdapter;

    private LoadDataScrollController mController;


    private ProgressDialog pd;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_recycle_swiperefresh);

        mRecycle = ((RecyclerView) findViewById(R.id.swipe_target));

        mSwipeRefresh = ((SwipeRefreshLayout) findViewById(R.id.swipe_refresh));

        mSwipeRefresh.setColorSchemeColors(Color.RED,Color.GREEN,Color.BLUE);

        /**
         * 創建控制器,同時使當前activity實現數據監聽回調接口
         */
        mController = new LoadDataScrollController(this);



        mAdapter = new HomeAdapter();

        //設置垂直的線性布局管理器,Orientation -->   VERTICAL:垂直   HORIZONTAL:水平
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);

        //StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);

        //添加分割線
        mRecycle.addItemDecoration(new DividerItemDecoration(getApplicationContext(), DividerItemDecoration.VERTICAL_LIST));


        mRecycle.setLayoutManager(layoutManager);

        mRecycle.setItemAnimator(new DefaultItemAnimator());

        mRecycle.setAdapter(mAdapter);

        mAdapter.refresh();

        /**
         * 設置監聽
         */
        mRecycle.addOnScrollListener(mController);

        mSwipeRefresh.setOnRefreshListener(mController);

    }

    @Override
    public void refresh() {
        //刷新的接口調
        mSwipeRefresh.postDelayed(new Runnable() {
            @Override
            public void run() {
                mAdapter.refresh();
                mSwipeRefresh.setRefreshing(false);
                mController.setLoadDataStatus(false);
            }
        },2000);
    }

    @Override
    public void loadMore() {
        //加載更多的接口回調
        pd = new ProgressDialog(this);
        pd.show();
        mSwipeRefresh.postDelayed(new Runnable() {
            @Override
            public void run() {
                mAdapter.add();
                //設置數據加載結束的監聽狀態
                mController.setLoadDataStatus(false);
                pd.dismiss();
            }
        },2000);
    }
}

貼個效果圖

這裡寫圖片描述

SwipeToLoadLayout實現上拉加載和下拉刷新

該刷新控件的方式類似於Ultra-pull-to-refresh的使用方式。

如下方式添加該庫:

 repositories {
        maven { url "https://jitpack.io" }
           }

 compile 'com.github.Aspsine:SwipeToLoadLayout:1.0.3'

首先我們需要自定義一個頭視圖和底部視圖,頭部試圖和底部試圖的用法相同,所以我們先定義一個頭部視圖類:

/**
 * 基礎的refreshHeadView
 */
public class RefreshHeaderView extends TextView implements SwipeRefreshTrigger, SwipeTrigger {

    public RefreshHeaderView(Context context) {
        super(context);
    }

    public RefreshHeaderView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public RefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void onRefresh() {
        //下拉到一定位置松開之後,調用此方法
        setText("refresh");

        Log.i("info","onRefresh");
    }

    @Override
    public void onPrepare() {

        //下拉之前調用此方法
        Log.i("info","onPrepare");
    }

    @Override
    public void onMove(int yScrolled, boolean isComplete, boolean automatic) {
        if (!isComplete) {
            //當前Y軸偏移量大於控件高度時,標識下拉到界限,顯示“松開已刷新”
            if (yScrolled >= getHeight()) {

            } else {
                //未達到偏移量

            }
        } 
        Log.i("info","onMove");
    }

    @Override
    public void onRelease() {
        //達到一定滑動距離,松開刷新時調用
        setText("onRelease");
        Log.i("info","onRelease");
    }

    @Override
    public void onComplete() {
        //加載完成之後調用此方法
        setText("complete");
        Log.i("info","onComplete");
    }

    @Override
    public void onReset() {
        //重置
        setText("onReset");
        Log.i("info","onReset");
    }
}

其需要實現接口SwipeRefreshTriggerSwipeTrigger

而底部需要實現SwipeTriggerSwipeLoadMoreTrigger

布局文件中如下使用




    

        

        

        
    



查找控件,設置監聽

        swipeToLoadLayout.setOnRefreshListener(this);
        swipeToLoadLayout.setOnLoadMoreListener(this);

在我們之前的代碼中,加入了log信息,我們可以看一下log信息。…代表多次onMove()方法多次調用。

05-10 10:30:34.396 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onPrepare
05-10 10:30:34.536 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
..........................................................................
05-10 10:30:34.886 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
05-10 10:30:34.896 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onRelease
05-10 10:30:34.906 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
..........................................................................
05-10 10:30:35.086 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
05-10 10:30:35.106 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onRefresh
05-10 10:30:37.116 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onComplete
05-10 10:30:37.416 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
..........................................................................
05-10 10:30:37.516 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
05-10 10:30:37.916 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onReset

首先會調用onPrepare()方法onMove()方法會一直調用,只要視圖有偏移,就會調用。下拉到一定距離之後,松開調用onRelaease(),回歸到刷新位置時回調onRefresh(),加載完成調用onComplete(),視圖開始縮小,最後隱藏之後調用onReset()

根據需求自定義視圖,

這裡寫圖片描述

定義我們的橢圓,使用自定義控件<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> /** * CircleView 圓盤控件,可以旋轉 * Created by Alex_MaHao on 2016/5/10. */ public class CircleView extends View { /** * 控件的半徑 */ private int mRadius; /** * 繪制弧形的畫筆 */ private Paint mArcPaint; /** * 繪制弧形的區域 */ private RectF mRange; private int[] colors = {Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN}; public CircleView(Context context) { this(context, null, 0); } public CircleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mArcPaint = new Paint(); mArcPaint.setAntiAlias(true); mArcPaint.setDither(true); mArcPaint.setStyle(Paint.Style.FILL); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = 0; int height = 0; int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 45, getResources().getDisplayMetrics()); } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 45, getResources().getDisplayMetrics()); } //獲取半徑 mRadius = Math.min(width, height) / 2; /** * 設置寬高為固定值 */ setMeasuredDimension(mRadius * 2, mRadius * 2); mRange = new RectF(0, 0, mRadius * 2, mRadius * 2); } @Override protected void onDraw(Canvas canvas) { float degree = 360/colors.length/2f; for (int i = 0; i < 8; i++) { mArcPaint.setColor(colors[i%4]); canvas.drawArc(mRange,-90f+degree*i,degree,true,mArcPaint); } } }

繪制頭部刷新試圖

**
 * 自定義的下拉刷新控件 頭部
 * Created by Alex_MaHao on 2016/5/10.
 */
public class CircleRefreshHeaderView extends RelativeLayout implements SwipeTrigger, SwipeRefreshTrigger {

    CircleView mCircleView;

    TextView mDescText;

    private ObjectAnimator anim;

    private boolean isRelease;

    public CircleRefreshHeaderView(Context context) {
        this(context, null, 0);
    }

    public CircleRefreshHeaderView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleRefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initView();
    }

    /**
     * 初始化布局
     */
    private void initView() {

        int circlewidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics());

        mCircleView = new CircleView(getContext());

        LinearLayout.LayoutParams circleParams = new LinearLayout.LayoutParams(circlewidth,circlewidth);

        mCircleView.setLayoutParams(circleParams);

        mDescText = new TextView(getContext());

        LinearLayout.LayoutParams descParams = new LinearLayout.LayoutParams(circlewidth*3, ViewGroup.LayoutParams.WRAP_CONTENT);

        descParams.gravity = Gravity.CENTER;
        descParams.setMargins(circlewidth/2,0,0,0);
        mDescText.setLayoutParams(descParams);
        mDescText.setTextSize(12);
        mDescText.setTextColor(Color.GRAY);
        mDescText.setText("下拉刷新");

        //添加線性的父布局
        LinearLayout ll = new LinearLayout(getContext());
        RelativeLayout.LayoutParams llParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        llParams.addRule(CENTER_IN_PARENT);
        ll.setLayoutParams(llParams);
        ll.setPadding(10,10,10,10);

        ll.addView(mCircleView);
        ll.addView(mDescText);

        addView(ll);
    }

    @Override
    public void onRefresh() {

        //開始刷新,啟動動畫
        anim = ObjectAnimator.ofFloat(mCircleView, "rotation", mCircleView.getRotation(), mCircleView.getRotation()+360f)
                .setDuration(500);
        anim.setRepeatCount(ValueAnimator.INFINITE);
        anim.setRepeatMode(ValueAnimator.RESTART);
        anim.start();

        mDescText.setText("正在加載數據");
    }

    @Override
    public void onPrepare() {
        isRelease = false;
    }

    @Override
    public void onMove(int yScroll, boolean isComplete, boolean b1) {
        if (!isComplete) {
            if (yScroll < getHeight()) {
                mDescText.setText("下拉刷新");
            } else {
                mDescText.setText("松開刷新更多");
            }

            //如果是仍在下拉狀態,則圓環跟隨滑動進行滾動
            if (!isRelease)
                mCircleView.setRotation(((float) yScroll) / getHeight() * 360f);
        }


    }

    @Override
    public void onRelease() {
        isRelease = true;
    }

    @Override
    public void onComplete() {
        anim.cancel();
        mDescText.setText("加載完成");
    }

    @Override
    public void onReset() {
        //重置時,將動畫置為初始狀態
        mCircleView.setRotation(0f);
    }
}

布局文件



    

        

        

        
    



public class SwipeToLayoutActivity extends AppCompatActivity implements OnRefreshListener, OnLoadMoreListener {



    private RecyclerView mRecycleView;

    SwipeToLoadLayout swipeToLoadLayout;

    private HomeAdapter adapter;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycle_swipetolayout);


        swipeToLoadLayout = ((SwipeToLoadLayout) findViewById(R.id.swipeToLoadLayout));


        mRecycleView = ((RecyclerView) findViewById(R.id.swipe_target));


        adapter = new HomeAdapter();

        //設置垂直的線性布局管理器,Orientation -->   VERTICAL:垂直   HORIZONTAL:水平
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);

//        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);

        //添加分割線
        mRecycleView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), DividerItemDecoration.VERTICAL_LIST));

        mRecycleView.setLayoutManager(layoutManager);

        mRecycleView.setItemAnimator(new DefaultItemAnimator());

        mRecycleView.setAdapter(adapter);

        adapter.refresh();

        /**
         * 設置下拉刷新和上拉加載監聽
         */
        swipeToLoadLayout.setOnRefreshListener(this);
        swipeToLoadLayout.setOnLoadMoreListener(this);

    }




    @Override
    public void onRefresh() {
        swipeToLoadLayout.postDelayed(new Runnable() {
            @Override
            public void run() {
                adapter.refresh();
                swipeToLoadLayout.setRefreshing(false);
            }
        },2000);
    }

    @Override
    public void onLoadMore() {
        swipeToLoadLayout.postDelayed(new Runnable() {
            @Override
            public void run() {

                adapter.add();
                swipeToLoadLayout.setLoadingMore(false);
            }
        },2000);
    }
}

OK。肯定有小伙伴使用該框架時一直報錯,為什麼,看框架的源碼,有如下一段

 this.mHeaderView = this.findViewById(id.swipe_refresh_header);
 this.mTargetView = this.findViewById(id.swipe_target);
 this.mFooterView = this.findViewById(id.swipe_load_more_footer);

可以看出,作者是根據固定的id值獲取的,所以在我們的布局文件中,必須使用固定的三個id。

如有需求,可移步我的github獲取源碼。源碼在systemwidgetdemo中。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved