Android RecyclerView的刷新分頁(yè)的實(shí)現(xiàn)
在開發(fā)中常常使用到刷新分頁(yè),這里實(shí)現(xiàn)一個(gè) RecyclerView 的簡(jiǎn)單的刷新分頁(yè)操作,測(cè)試效果見(jiàn)文末,實(shí)現(xiàn)過(guò)程參考如下:
實(shí)現(xiàn)思路
- 加載更多數(shù)據(jù)使用到 RecyclerView 加載多種布局,根據(jù) ViewType 判斷加載數(shù)據(jù) Item 還是加載 FooterItem ;
- 通過(guò)線程模擬加載數(shù)據(jù);
- 為 RecyclerView 添加 addOnScrollListener 事件來(lái)監(jiān)聽(tīng)用戶的滑動(dòng)操作;
- 根據(jù)用戶滑動(dòng)狀態(tài)以及具體情況開始加載數(shù)據(jù)
- 通知數(shù)據(jù)更新;
如何獲得 firstVisibleItemPosition
為了能夠在數(shù)據(jù)加載中動(dòng)態(tài)判斷什么時(shí)候加載數(shù)據(jù),需要知道屏幕上顯示的第一個(gè)可見(jiàn)的 Item 的位置,當(dāng)然了這里使用的是布局管理器是 LinearLayoutManager ,這樣查找屏幕上第一個(gè)可見(jiàn)的 Item 就顯得容易多了,下面介紹一些 LinearLayoutManager 的四個(gè)方法:
findFirstVisibleItemPosition()
獲得屏幕上第一個(gè)可見(jiàn) Item 的 position,只要該 Item 有一部分可見(jiàn),那么返回的 position 就是該Item 的 position。
findFirstCompletelyVisibleItemPosition()
獲得屏幕上第一個(gè)完整可見(jiàn)的 Item 的 position,只要該 Item 有一部分不可見(jiàn),那么返回的 position 就是該 Item 對(duì)應(yīng)的下一個(gè)能顯示完整的 Item 的position。
findLastVisibleItemPosition()
獲得屏幕上最后一個(gè)可見(jiàn) Item 的 position,只要該 Item 有一部分可見(jiàn),那么返回的 position 就是該Item 的 position。
findLastCompletelyVisibleItemPosition()
獲得屏幕上最后一個(gè)完整可見(jiàn)的 Item 的 position,只要該 Item 有一部分不可見(jiàn),那么返回的 position 就是該 Item 對(duì)應(yīng)的上一個(gè)能顯示完整的 Item 的position。
準(zhǔn)備數(shù)據(jù)
/**
* 初始化數(shù)據(jù)
* @return
*/
public void initData(){
for (int i=0;i<30;i++){
arrayList.add("第"+i+"條數(shù)據(jù)");
}
}
/**
* 線程模擬加載數(shù)據(jù)
*/
class LoadDataThread extends Thread{
@Override
public void run() {
initData();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//通知主線程更新數(shù)據(jù)
Message message = handler.obtainMessage();
message.what = UPDATE_DATA;
message.obj = arrayList;
handler.sendMessage(message);
}
}
代碼參考
主布局
<?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="match_parent" tools:context="com.manu.mrecyclerview.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </LinearLayout>
Item布局
/**item.xml**/ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp"> <TextView android:id="@+id/tv_recycle" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="data" android:background="#cac3c3" android:padding="10dp" android:textSize="20sp"/> </LinearLayout>
/**item_footer.xml**/ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal"> <ProgressBar style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/progressBar" /> <TextView android:text="正在努力加載中,請(qǐng)稍后..." android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView" /> </LinearLayout>
Adapter
這里使用了 RecyclerView 根據(jù)不同的 ViewType 加載多種布局的用法,使用時(shí)根據(jù)不同的布局創(chuàng)建不同的 ViewHolder , 然后根據(jù)不同的 Viewholder 為對(duì)應(yīng)的 Item 添加數(shù)據(jù),注意 getItemViewType() 方法的用法,Adapter 代碼參考如下:
/**
* Created by jzman on 2017/6/04
* RecycleView的Adapter
*/
public class RvAdapter1 extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
View.OnClickListener{
private static final int ITEM_FOOTER = 0x1;
private static final int ITEM_DATA = 0x2;
private Context mContext;
private RecyclerView recyclerView;
private ArrayList<String> mList;
public RvAdapter1() {}
public RvAdapter1(Context mContext, ArrayList<String> mList) {
this.mContext = mContext;
this.mList = mList;
}
public void setmList(ArrayList<String> mList) {
this.mList = mList;
}
/**
* 用于創(chuàng)建ViewHolder
* @param parent
* @param viewTypez
* @return
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view ;
RecyclerView.ViewHolder vh = null;
switch (viewType){
case ITEM_DATA:
view = LayoutInflater.from(mContext).inflate(R.layout.item,null);
view.setOnClickListener(this);
vh = new DataViewHolder(view);
//使用代碼設(shè)置寬高(xml布局設(shè)置無(wú)效時(shí))
view.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
break;
case ITEM_FOOTER:
view = LayoutInflater.from(mContext).inflate(R.layout.item_footer,null);
//使用代碼設(shè)置寬高(xml布局設(shè)置無(wú)效時(shí))
vh = new FooterViewHolder(view);
view.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
break;
}
return vh;
}
/**
* 獲取Item的View類型
* @param position
* @return
*/
@Override
public int getItemViewType(int position) {
//根據(jù) Item 的 position 返回不同的 Viewtype
if (position == (getItemCount())-1){
return ITEM_FOOTER;
}else{
return ITEM_DATA;
}
}
/**
* 綁定數(shù)據(jù)
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof DataViewHolder){
DataViewHolder dataViewHolder = (DataViewHolder) holder;
dataViewHolder.tv_data.setText(mList.get(position));
}else if (holder instanceof FooterViewHolder){
}
}
/**
* 選項(xiàng)總數(shù)
* @return
*/
@Override
public int getItemCount() {
return mList.size()+1;
}
@Override
public void onClick(View view) {
//根據(jù)RecyclerView獲得當(dāng)前View的位置
int position = recyclerView.getChildAdapterPosition(view);
//程序執(zhí)行到此,會(huì)去執(zhí)行具體實(shí)現(xiàn)的onItemClick()方法
if (onItemClickListener!=null){
onItemClickListener.onItemClick(recyclerView,view,position,mList.get(position));
}
}
/**
* 創(chuàng)建ViewHolder
*/
public static class DataViewHolder extends RecyclerView.ViewHolder{
TextView tv_data;
public DataViewHolder(View itemView) {
super(itemView);
tv_data = (TextView) itemView.findViewById(R.id.tv_recycle);
}
}
/**
* 創(chuàng)建footer的ViewHolder
*/
public static class FooterViewHolder extends RecyclerView.ViewHolder{
public FooterViewHolder(View itemView) {
super(itemView);
}
}
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
/**
* 定義RecyclerView選項(xiàng)單擊事件的回調(diào)接口
*/
public interface OnItemClickListener{
//參數(shù)(父組件,當(dāng)前單擊的View,單擊的View的位置,數(shù)據(jù))
void onItemClick(RecyclerView parent,View view, int position, String data);
}
/**
* 將RecycleView附加到Adapter上
*/
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
this.recyclerView= recyclerView;
}
/**
* 將RecycleView從Adapter解除
*/
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
this.recyclerView = null;
}
}
MainActivity
這里主要注意 rv.addOnScrollListener(new OnScrollListener() ...里面的具體實(shí)現(xiàn),MainActivity 代碼參考如下:
/**
* Created by jzman on 2017/6/04 0013.
*/
public class MainActivity extends AppCompatActivity {
private static final int UPDATE_DATA = 0x3;
private RecyclerView rv;
RvAdapter1 adapter;
private ArrayList<String> arrayList = new ArrayList<>();
//加載更多數(shù)據(jù)時(shí)最后一項(xiàng)的索引
private int lastLoadDataItemPosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv = (RecyclerView) findViewById(R.id.rv);
//設(shè)置布局管理器
rv.setLayoutManager(new LinearLayoutManager(this));//線性
// rv.setLayoutManager(new GridLayoutManager(this,4));//線性
// rv.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));//線性
initData();
adapter = new RvAdapter1(this,arrayList);
adapter.setOnItemClickListener(new RvAdapter1.OnItemClickListener() {
@Override
public void onItemClick(RecyclerView parent, View view, int position, String data) {
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
});
rv.addOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == SCROLL_STATE_IDLE &&
lastLoadDataItemPosition == adapter.getItemCount()){
new LoadDataThread().start();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager){
LinearLayoutManager manager = (LinearLayoutManager) layoutManager;
int firstVisibleItem = manager.findFirstVisibleItemPosition();
int l = manager.findLastCompletelyVisibleItemPosition();
lastLoadDataItemPosition = firstVisibleItem+(l-firstVisibleItem)+1;
}
}
});
rv.setAdapter(adapter);
}
/**
* 初始化數(shù)據(jù)
* @return
*/
public void initData(){
for (int i=0;i<25;i++){
arrayList.add("第"+i+"條數(shù)據(jù)");
}
}
/**
* 線程模擬加載數(shù)據(jù)
*/
class LoadDataThread extends Thread{
@Override
public void run() {
initData();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = handler.obtainMessage();
message.what = UPDATE_DATA;
message.obj = arrayList;
handler.sendMessage(message);
}
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case UPDATE_DATA:
arrayList = (ArrayList<String>) msg.obj;
adapter.setmList(arrayList);
adapter.notifyDataSetChanged();
break;
}
}
};
}
測(cè)試效果

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android自定義ListView實(shí)現(xiàn)下拉刷新上拉加載更多
- android RecycleView實(shí)現(xiàn)下拉刷新和上拉加載
- 解決android viewmodel 數(shù)據(jù)刷新異常的問(wèn)題
- Android巧用XListView實(shí)現(xiàn)萬(wàn)能下拉刷新控件
- Android自定義view仿微信刷新旋轉(zhuǎn)小風(fēng)車
- Android自定義控件ListView下拉刷新的代碼
- Android ExpandableListView實(shí)現(xiàn)下拉刷新和加載更多效果
- android使用SwipeRefreshLayout實(shí)現(xiàn)ListView下拉刷新上拉加載
- android使用PullToRefresh框架實(shí)現(xiàn)ListView下拉刷新上拉加載更多
- Android 中RecyclerView頂部刷新實(shí)現(xiàn)詳解
- Android四種方式刷新View的操作方法
相關(guān)文章
解析Android 8.1平臺(tái)SystemUI 導(dǎo)航欄加載流程
這篇文章主要介紹了Android 8.1平臺(tái)SystemUI 導(dǎo)航欄加載流程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
Android開發(fā)應(yīng)用中Broadcast Receiver組件詳解
本篇文章主要介紹了Android開發(fā)應(yīng)用中Broadcast Receiver組件詳解,想要學(xué)習(xí)的同學(xué)可以了解一下。2016-11-11
Android PowerManagerService省電模式策略控制
這篇文章主要介紹了Android PowerManagerService省電模式策略控制,本文基于前兩篇文章的基礎(chǔ)介紹展開詳情,感興趣的小伙伴可以參考一下2022-08-08
使用Docker來(lái)加速構(gòu)建Android應(yīng)用的基本部署思路解析
這篇文章主要介紹了使用Docker來(lái)加速構(gòu)建Android應(yīng)用的部署思路解析,在服務(wù)器中通過(guò)Docker鏡像來(lái)獲得更高效的開發(fā)和測(cè)試流程,需要的朋友可以參考下2016-01-01
Android開發(fā)flow常見(jiàn)API的使用示例詳解
這篇文章主要為大家介紹了Android開發(fā)flow常見(jiàn)API的使用示例詳解,希望能夠幫助大家更好的掌握f(shuō)low使用,熟練的應(yīng)用于各種場(chǎng)景,祝大家多多進(jìn)步,早日升職加薪2022-08-08

