本文執行個體為大家分享了Android自訂下拉重新整理上拉載入的具體實現步驟,供大家參考,具體內容如下
實現的方式是SwipeRefreshLayout + RecyclerView 的VIewType
首先看效果:
總的思路:
布局檔案
<android.support.v4.widget.SwipeRefreshLayout android:layout_marginTop="?attr/actionBarSize" android:id="@+id/one_refresh" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/one_recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v7.widget.RecyclerView> </android.support.v4.widget.SwipeRefreshLayout>
下拉重新整理的實現思路
用於測試的Model
public class TestModel { private String mTitle; private String mDesc; private String mTime; public TestModel(String mTitle, String mDesc, String mTime) { this.mTitle = mTitle; this.mDesc = mDesc; this.mTime = mTime; } //...一堆getXxx ,setXxx方法 //equals必寫,添加資料時候用於判斷 @Override public boolean equals(Object o) { TestModel model = (TestModel) o; if (!mTitle.equals(model.getmTitle())) { return false; } else if (!mDesc.equals(model.getmDesc())) { return false; } else if (!mTime.equals(model.getmTitle())) { return false; } return true; }
類比擷取網路資料的代碼
private class GetData { int size = 0 ; int max = 25; //資料的最大值 public void setStart(int size) { this.size = size; } //根據size擷取指定大小的List,最大不能超過max public List<TestModel> initData(int size) { List<TestModel> mDatas = new ArrayList<>(); TestModel model = null; for (int i = start; i < ((size + start) > max ? max : (size + start)); i++) { model = new TestModel("Title" + i, "Desc" + i, "今天 11:30"); mDatas.add(model); } start += size; return mDatas; } }
資料擷取並通知初始化RecyclerView
public void initData() { if (getData == null) { getData = new GetData(); } mLists = getData.initData(size); //擷取預設顯示的數量的item mhandler.sendEmptyMessage(REFRESH); //通知handler更新 }
Handler中用於處理第一次顯示資料和以後重新整理操作的代碼
if (msg.what == REFRESH) {if (mAdapter == null) {mAdapter = new OneAdapter(mContext);mAdapter.setmDatas(mLists);//設定資料//...對適配器的設定,這裡先省去,免得混淆mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));mRecyclerView.setAdapter(mAdapter); } else { mAdapter.setmDatas(mLists); mAdapter.cleadnCount(); mAdapter.notifyDataSetChanged(); } initRefresh(); //判斷refreshLayout是否在重新整理,是的話取消重新整理操作 .就不貼代碼了顯的亂糟糟
RefreshLayout的重新整理事件
mRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { new Thread(mRunnable).start();//runnable調用了initData()方法; } });
此時就可以對重新整理操作做出響應了,與平時使用RefreshLayout的操作一樣
上拉重新整理的實現思路(主要在適配器中,activity中只需要一個當需要載入更多的時候更新資料來源就行)
普通內容的布局
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <ImageView android:scaleType="centerInside" android:id="@+id/item_head" android:layout_width="70dp" android:layout_height="70dp" android:layout_gravity="center" android:layout_margin="5dp" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="5dp" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/item_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" android:gravity="center_vertical" android:text="Title" android:textSize="20sp" /> <TextView android:id="@+id/item_desc" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" android:gravity="center_vertical" android:text="Desc" android:textSize="16sp" /> <TextView android:id="@+id/item_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical|right" android:layout_marginRight="14dp" android:layout_weight="1" android:gravity="center_vertical|right" android:text="Time" android:textSize="20sp" /> </LinearLayout> </LinearLayout></android.support.v7.widget.CardView>
載入更多的內容布局(預設顯示ProgressBar,沒有更多的表徵圖隱藏)
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <ImageView android:id="@+id/load_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|right" android:layout_weight="1" android:scaleType="centerInside" android:src="@mipmap/ic_launcher" android:visibility="gone" /> <ProgressBar android:id="@+id/load_progress" style="@style/Widget.AppCompat.ProgressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|right" android:layout_weight="1" /> <TextView android:id="@+id/load_tv" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:layout_weight="1" android:gravity="center_vertical|left" android:text="正在載入更多...." android:textColor="@color/colorBlank" android:textSize="20sp" /></LinearLayout>
itemCount(因為我們要在最後顯示資訊,所以item的總數應該是加1,但是也是分情況的:
@Override public int getItemCount() { if (mDatas.size() > minShowLoad) { //當前item能將螢幕顯示滿 return mDatas.size() + 1; //則預設顯示載入或者沒有更多 } return mDatas.size(); //如果不能顯示滿,則不顯示載入和沒有更多 }
getViewType(根據不同的位置顯示不同的type)
@Override public int getItemViewType(int position) { if (position == mDatas.size()) { return VIEWTYPE_LOAD; //最後一個顯示載入資訊 } return VIEWTYPE_CONTENT;//否則顯示正常布局 }
正常內容的ViewHolder
//內容布局 private class ContentViewHolder extends RecyclerView.ViewHolder { private TextView mTitle; private TextView mDesc; private TextView mTime; private ImageView mHead; private View itemView; public ContentViewHolder(View itemView) { super(itemView); this.itemView = itemView; mTitle = (TextView) itemView.findViewById(R.id.item_title); mDesc = (TextView) itemView.findViewById(R.id.item_desc); mTime = (TextView) itemView.findViewById(R.id.item_time); mHead = (ImageView) itemView.findViewById(R.id.item_head); } }
載入資訊的ViewHolder
//載入更多的布局 (用於顯示正在載入和沒有更多 private class LoadMoreViewHolder extends RecyclerView.ViewHolder { private ImageView mImage; private ProgressBar mProgress; private TextView mMsg; public LoadMoreViewHolder(View itemView) { super(itemView); mImage = (ImageView) itemView.findViewById(R.id.load_image); mProgress = (ProgressBar) itemView.findViewById(R.id.load_progress); mMsg = (TextView) itemView.findViewById(R.id.load_tv); } }
onCreateViewHolder中初始化不同的ViewHolder
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = null; switch (viewType) { case 1: itemView = LayoutInflater.from(mContext).inflate(R.layout.load_layout, parent, false); return new LoadMoreViewHolder(itemView); case 2: itemView = LayoutInflater.from(mContext).inflate(R.layout.item_test, parent, false); return new ContentViewHolder(itemView); } return null; }
定義一個回調,用於當顯示載入的時候通知activity更新資料
public interface onLoadMoreListener { void loadMore(); } //全域變數private onLoadMoreListener onLoadMoreListener;
onBindViewHolder(對不同的情況進行資料顯示)
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof ContentViewHolder) { TestModel model = mDatas.get(position); ((ContentViewHolder) holder).mTitle.setText(model.getmTitle()); ((ContentViewHolder) holder).mDesc.setText(model.getmDesc()); ((ContentViewHolder) holder).mTime.setText(model.getmTime()); } else if (holder instanceof LoadMoreViewHolder) { if (mDatas.size() < itemsCount) { //沒有更多 ((LoadMoreViewHolder) holder).mMsg.setText("沒有更多了~~~"); ((LoadMoreViewHolder) holder).mProgress.setVisibility(View.GONE); ((LoadMoreViewHolder) holder).mImage.setVisibility(View.VISIBLE); } else { onLoadMoreListener.loadMore(); ((LoadMoreViewHolder) holder).mMsg.setText("正在載入更多...."); ((LoadMoreViewHolder) holder).mProgress.setVisibility(View.VISIBLE); ((LoadMoreViewHolder) holder).mImage.setVisibility(View.GONE); } } }
載入更多的回調在Activity中的使用
mAdapter.setOnLoadMoreListener(new OneAdapter.onLoadMoreListener() { @Override public void loadMore() { //增加資料到資料來源中 //調用adapter的addData方法 //更新適配器顯示 }}
至此下拉重新整理上拉載入就完成了,Demo地址:SwipeToRefreshTest。
以上就是Android自訂下拉重新整理上拉載入的全部內容,希望能給大家一個參考,也希望大家多多支援雲棲社區。