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();
}
}
}
}