RecyclerView實現(xiàn)上拉加載

RecyclerView是 Android 兼容包V21中新推出的列表類目尖,它的自定義化強的優(yōu)點足以讓它能夠取代GridView和ListView姥卢,本文將結(jié)合SwipeRefreshLayout與RecyclerView講解如何實現(xiàn)下拉刷新和自動加載的代碼,不廢話直接上代碼捌刮!

需要的依賴:

compile 'com.android.support:appcompat-v7:21.0.0' compile 'com.android.support:recyclerview-v7:21.0.0' compile 'com.android.support:cardview-v7:21.0.0' compile 'com.android.support:support-v4:21.0.0'

我們下拉刷新直接使用

android.support.v4.widget.SwipeRefreshLayout
這個庫來使用辉巡,符合MD風格的下拉刷新太雨!

看看我們的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=".MainActivity">

           <android.support.v4.widget.SwipeRefreshLayout
                android:id="@+id/swipe_container"
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
            <android.support.v7.widget.RecyclerView
                android:id="@+id/my_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>

下面放出我們的主要代碼

package suzhou.dataup.cn.myapplication.fragment;

import android.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;

import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.InjectView;
import suzhou.dataup.cn.myapplication.R;
import suzhou.dataup.cn.myapplication.adputer.AndroidResoutAdputer;
import suzhou.dataup.cn.myapplication.base.BaseFragment;
import suzhou.dataup.cn.myapplication.bean.HomeResoutBean;
import suzhou.dataup.cn.myapplication.callback.MyHttpCallBcak;
import suzhou.dataup.cn.myapplication.constance.CountUri;
import suzhou.dataup.cn.myapplication.mangers.OkHttpClientManager;
import suzhou.dataup.cn.myapplication.utiles.LogUtil;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link AndroidFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link AndroidFragment#newInstance} factory method to
 * create an instance of this fragment.
 * 安卓控件的界面的界面
 */
public class AndroidFragment extends BaseFragment {
    int lastVisibleItem = 0;
    int index = 1;
    int temp = 0;
    @InjectView(R.id.my_recycler_view)
    RecyclerView recyclerView;
    @InjectView(R.id.swipe_container)
    SwipeRefreshLayout mSwipeContainer;
    AndroidResoutAdputer mMyadputer;
    List<HomeResoutBean.ResultsEntity> mResultsEntityList = new ArrayList<>();
    boolean isFirstLoda = true;

    public AndroidFragment() {
        super(R.layout.fragment_weal);
    }

    @Override
    protected void initHead() {
    }

    @Override
    protected void initContent() {
        // 創(chuàng)建一個線性布局管理器
        final LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(mLayoutManager);//設置線性的管理器!
        //設置刷新時的不同的顏色茫蛹!
        mSwipeContainer.setColorScheme(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light);
        //google官方的下拉刷新操刀!
        mSwipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                lastVisibleItem = 0;
                isFirstLoda = true;
                mResultsEntityList.clear();
                index = 1;
                getData(index);

            }
        });
        //監(jiān)聽recyclerView的上滑動的位置來進行積蓄的加載更多的數(shù)據(jù)
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            //滾動中調(diào)用
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //獲取總的適配器的數(shù)量
                int totalCount = mMyadputer.getItemCount();
                LogUtil.e("總的數(shù)目  " + totalCount);
                LogUtil.e("滾動的狀態(tài)  " + newState);
                //這個就是判斷當前滑動停止了,并且獲取當前屏幕最后一個可見的條目是第幾個婴洼,當前屏幕數(shù)據(jù)已經(jīng)顯示完畢的時候就去加載數(shù)據(jù)
                if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == mMyadputer.getItemCount()) {
                    mSwipeContainer.setRefreshing(true);//刷新完畢!
                    //請求數(shù)據(jù)
                    index++;
                    getData(index);
                }
            }

            //滾動停止后調(diào)用
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //獲取最后一個可見的條目的位置,如果是線性加載更多就換成這個
                lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
            }
        });
    }

    @Override
    protected void initLocation() {
        getData(index);
    }


    @Override
    protected void initLogic() {
    }

    @Override
    protected void isShow() {
        if (mMyadputer != null) {
            lastVisibleItem = 0;
            isFirstLoda = true;
            mResultsEntityList.clear();
            index = 1;
            getData(index);
            LogUtil.e("可見了");
        }

    }

    @Override
    protected void isGone() {

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.reset(this);
    }

    //獲取福利的數(shù)據(jù)
    private void getData(int index) {
        OkHttpClientManager.get(CountUri.BASE_URI + "/Android/20/" + index + "", new MyHttpCallBcak() {
            @Override
            public void onFailure(Request request, IOException e) {
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mSwipeContainer.setRefreshing(false);//刷新完畢!
                    }
                });
            }

            @Override
            public void onResponse(final Response response) {
                try {
                    if (response != null) {
                        HomeResoutBean homeResoutBean = mGson.fromJson(response.body().string(), HomeResoutBean.class);
                        List<HomeResoutBean.ResultsEntity> results = homeResoutBean.results;
                        for (HomeResoutBean.ResultsEntity result : results) {
                            mResultsEntityList.add(result);
                        }
                        if (isFirstLoda) {
                            getActivity().runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mSwipeContainer.setRefreshing(false);//刷新完畢!
                                    mMyadputer = new AndroidResoutAdputer(mResultsEntityList, options_base, mLayoutUtil);
                                    recyclerView.setAdapter(mMyadputer);
                                    recyclerView.setItemAnimator(new DefaultItemAnimator());
                                    isFirstLoda = false;
                                }
                            });
                        } else {
                            getActivity().runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mSwipeContainer.setRefreshing(false);//刷新完畢!
                                    mMyadputer.notifyDataSetChanged();
                                }
                            });

                        }
                    } else {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getActivity(), "獲取服務器數(shù)據(jù)失敗骨坑。。柬采。", Toast.LENGTH_SHORT).show();
                            }
                        });

                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

最重要的說明已經(jīng)在代碼注釋中有了欢唾,主要就是監(jiān)聽rcy的滾動監(jiān)聽,然后監(jiān)聽滑動停止時候的位置

如果是瀑布流如何實現(xiàn)上拉加載更多呢粉捻!so easy請看代碼

   //滾動停止后調(diào)用
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //獲取最后一個可見的條目的位置,如果是線性加載更多就換成這個我們只需要監(jiān)聽他的最后一個返回的位置就行啦匈辱!比較最大哪個數(shù)值就是最后一個顯示的postion
//                lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
                int[] firstVisibleItemPositions = mLayoutManager.findLastVisibleItemPositions(null);
                for (int firstVisibleItemPosition : firstVisibleItemPositions) {
                    temp = firstVisibleItemPosition;
                    if (lastVisibleItem < temp) {
                        lastVisibleItem = firstVisibleItemPosition;//標記最后一個顯示的postion
                        LogUtil.e("停止可見的位置是  " + firstVisibleItemPosition);
                    }
                }
            }
        });

TIP 我們?nèi)绾卧O置自動刷新呢!其實谷歌已經(jīng)提供方法了但是很遺憾這個是私有的方法杀迹,怎么辦呢亡脸!反射調(diào)用唄押搪!上菜。浅碾。

  package suzhou.dataup.cn.myapplication.utiles;

import android.support.v4.widget.SwipeRefreshLayout;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 作者:liujingyuan on 2015/11/3 21:51
 * 郵箱:906514731@qq.com
 */
public class SwipContainerUtiles {
    //通過反射調(diào)用起私有的自動刷新的方法大州!
    public static void setRefreshing(SwipeRefreshLayout refreshLayout, boolean refreshing, boolean notify) {
        Class<? extends SwipeRefreshLayout> refreshLayoutClass = refreshLayout.getClass();
        if (refreshLayoutClass != null) {

            try {
                Method setRefreshing = refreshLayoutClass.getDeclaredMethod("setRefreshing", boolean.class, boolean.class);
                setRefreshing.setAccessible(true);
                setRefreshing.invoke(refreshLayout, refreshing, notify);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

}

好了以上就可以輕松的實現(xiàn)自動刷新和上拉加載啦!Demo地址在 https://github.com/l123456789jy/FilveFlavours

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垂谢,一起剝皮案震驚了整個濱河市厦画,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滥朱,老刑警劉巖根暑,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異徙邻,居然都是意外死亡排嫌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門缰犁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淳地,“玉大人,你說我怎么就攤上這事帅容∑南螅” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵并徘,是天一觀的道長遣钳。 經(jīng)常有香客問我,道長麦乞,這世上最難降的妖魔是什么耍贾? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮路幸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘付翁。我一直安慰自己简肴,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布百侧。 她就那樣靜靜地躺著砰识,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佣渴。 梳的紋絲不亂的頭發(fā)上辫狼,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音辛润,去河邊找鬼膨处。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的真椿。 我是一名探鬼主播鹃答,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼突硝!你這毒婦竟也來了测摔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤解恰,失蹤者是張志新(化名)和其女友劉穎锋八,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體护盈,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡挟纱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了黄琼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片樊销。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖脏款,靈堂內(nèi)的尸體忽然破棺而出围苫,到底是詐尸還是另有隱情,我是刑警寧澤撤师,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布剂府,位于F島的核電站,受9級特大地震影響剃盾,放射性物質(zhì)發(fā)生泄漏腺占。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一痒谴、第九天 我趴在偏房一處隱蔽的房頂上張望衰伯。 院中可真熱鬧,春花似錦积蔚、人聲如沸意鲸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怎顾。三九已至,卻和暖如春漱贱,著一層夾襖步出監(jiān)牢的瞬間槐雾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工幅狮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留募强,地道東北人株灸。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像钻注,于是被迫代替她去往敵國和親蚂且。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

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