SwipeRecyclerView 的下拉重新整理和載入更多的實現,simple版,有引入包的過程
參考連結,框架地址
SwipeRecyclerView
效果圖:
- 下拉重新整理
- 載入更多
本部落格內容
- 導包步驟
- 關鍵點,易出錯地方說明
- 完整程式碼
0. 導包步驟
Gradle
implementation 'com.yanzhenjie:recyclerview-swipe:1.1.4'
關鍵點,易出錯地方
- 第一次載入資料。一定要掉用方法 不然重新整理和載入更多失效
mRecyclerView.loadMoreFinish(false, true);
- 自定義載入更多 ,實現介面
SwipeMenuRecyclerView.LoadMoreView,
注:載入更多動畫,預設只有一個,可以設定顏色,如果要其他載入動畫,需要自定義,本人能力有限,暫時不會,會後續更新
完整程式碼:(相關注釋在程式碼裡)
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="text_color">#FF333333</color>
<color name="red_normal">#FF0000</color>
<color name="red_pressed">#FF6666</color>
<color name="green_normal">#37C000</color>
<color name="green_pressed">#30A070</color>
<color name="purple_normal">#9932CC</color>
<color name="purple_pressed">#9F79EE</color>
<color name="white">#FFFFFFFF</color>
<color name="white_pressed">#FFCFCFCF</color>
<color name="divider_color">#FFB7B2B2</color>
</resources>
recyclerview_demo_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="wrap_content">
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="名字"
android:textSize="45dp" />
</LinearLayout>
layout_fotter_loadmore.xml
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android">
<com.yanzhenjie.loading.LoadingView
android:id="@+id/loading_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="@+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:visibility="gone"/>
</merge>
activity_main.xml
<?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"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.yanzhenjie.recyclerview.swipe.SwipeMenuRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
RecyclerViewAdaper.java
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
public class RecyclerViewAdaper extends RecyclerView.Adapter<RecyclerViewAdaper.MyHoler> {
private List<String> list;
public RecyclerViewAdaper(List<String> list) {
this.list = list;
}
@NonNull
@Override
public MyHoler onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_demo_item,viewGroup,false);
MyHoler myHoler = new MyHoler(view);
return myHoler;
}
@Override
public void onBindViewHolder(@NonNull MyHoler myHoler, int i) {
myHoler.name.setText(list.get(i));
}
@Override
public int getItemCount() {
return list.size();
}
public void notifyDataSetChanged(List<String> mDataList) {
this.list = mDataList;
this.notifyDataSetChanged();
}
public class MyHoler extends RecyclerView.ViewHolder {
TextView name;
public MyHoler(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
}
}
}
MainActivity.java
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.yanzhenjie.loading.LoadingView;
import com.yanzhenjie.recyclerview.swipe.SwipeItemClickListener;
import com.yanzhenjie.recyclerview.swipe.SwipeMenuRecyclerView;
import com.yanzhenjie.recyclerview.swipe.widget.DefaultItemDecoration;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private SwipeRefreshLayout mRefreshLayout;
private SwipeMenuRecyclerView mRecyclerView;
private RecyclerViewAdaper mAdapter;
private List<String> mDataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadMore();
}
private void loadMore() {
mRefreshLayout = findViewById(R.id.refreshLayout);
mRefreshLayout.setOnRefreshListener(mRefreshListener); // 重新整理監聽。
mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); // 佈局管理者
mRecyclerView.addItemDecoration(new DefaultItemDecoration(ContextCompat.getColor(this, R.color.divider_color))); // 分割線樣式
mRecyclerView.setSwipeItemClickListener(mItemClickListener);// item點選事件
// 自定義的核心就是DefineLoadMoreView類。
DefineLoadMoreView loadMoreView = new DefineLoadMoreView(this);
// mRecyclerView.setAutoLoadMore(false); // 拉倒最下面時,是手動點選載入更多,還是自動載入更多,手動載入無載入更多動畫
// mRecyclerView.addHeaderView(loadMoreView); // 無效
mRecyclerView.addFooterView(loadMoreView); // 新增為Footer。
mRecyclerView.setLoadMoreView(loadMoreView); // 設定LoadMoreView更新監聽。
mRecyclerView.setLoadMoreListener(mLoadMoreListener);
mAdapter = new RecyclerViewAdaper(mDataList);
mRecyclerView.setAdapter(mAdapter);
// 請求伺服器載入資料。
loadData();
}
/**
* Item點選監聽。
*/
private SwipeItemClickListener mItemClickListener = new SwipeItemClickListener() {
@Override
public void onItemClick(View itemView, int position) {
Toast.makeText(MainActivity.this, "第" + position + "個", Toast.LENGTH_SHORT).show();
}
};
/**
* 下拉重新整理控制。
* 重新整理頁面到初始載入的 item ,目的是使載入更多繼續有效
*/
private SwipeRefreshLayout.OnRefreshListener mRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mRecyclerView.postDelayed(new Runnable() {
@Override
public void run() {
mRefreshLayout.setRefreshing(false);
loadData();
}
}, 1000); // 延時模擬請求伺服器。
}
};
/**
* 載入更多。
* 第一次載入更多現實無資料載入
* 使用下拉重新整理
* 第二次載入更多資料,有更多資料被載入
*/
int i = 1; // i 只是為了更明顯顯示效果,可以刪除
private SwipeMenuRecyclerView.LoadMoreListener mLoadMoreListener = new SwipeMenuRecyclerView.LoadMoreListener() {
@Override
public void onLoadMore() {
mRecyclerView.postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "" + i, Toast.LENGTH_SHORT).show();
if (i == 1) {
mRecyclerView.loadMoreFinish(false, false);
i++;
} else {
mRecyclerView.loadMoreFinish(false, true);
List<String> strings = createDataList(mAdapter.getItemCount());
mDataList.addAll(strings);
mAdapter.notifyItemRangeInserted(mDataList.size() - strings.size(), strings.size());
}
}
}, 1000);// 延時1000ms,執行
}
};
// 載入更多是呼叫此方法 新增更多資料
protected List<String> createDataList(int start) {
List<String> strings = new ArrayList<>();
for (int i = start; i < start + 20; i++) {
strings.add("第" + i + "個Item");
}
return strings;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
return true;
}
/**
* 第一次載入資料。一定要掉用方法 mRecyclerView.loadMoreFinish(false, true); 不然重新整理和載入更多失效
*/
private void loadData() {
mDataList = createDataList(0);
mAdapter.notifyDataSetChanged(mDataList);
mRefreshLayout.setRefreshing(false);
// 第一次載入資料:一定要掉用這個方法。
// 第一個引數:表示此次資料是否為空,假如你請求到的list為空(== null || list.size == 0),那麼這裡就要true。
// 第二個引數:表示是否還有更多資料,根據伺服器返回給你的page等資訊判斷是否還有更多,這樣可以提供效能,如果不能判斷則傳true。
mRecyclerView.loadMoreFinish(false, true);
}
/**
* 這是這個類的主角,如何自定義LoadMoreView。
*/
static final class DefineLoadMoreView extends LinearLayout implements SwipeMenuRecyclerView.LoadMoreView, View.OnClickListener {
private LoadingView mLoadingView; // 載入更多的動畫
private TextView mTvMessage;
private SwipeMenuRecyclerView.LoadMoreListener mLoadMoreListener;
public DefineLoadMoreView(Context context) {
super(context);
setLayoutParams(new ViewGroup.LayoutParams(-1, -2));
setGravity(Gravity.CENTER);
setVisibility(GONE);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int minHeight = (int) (displayMetrics.density * 60 + 0.5);
setMinimumHeight(minHeight);
inflate(context, R.layout.layout_fotter_loadmore, this);
mLoadingView = findViewById(R.id.loading_view);
mTvMessage = findViewById(R.id.tv_message);
int color1 = ContextCompat.getColor(getContext(), R.color.green_normal);
int color2 = ContextCompat.getColor(getContext(), R.color.purple_normal);
int color3 = ContextCompat.getColor(getContext(), R.color.colorAccent);
mLoadingView.setCircleColors(color1, color2, color3);
// 載入更多動畫,只有圓圈轉動的動畫
setOnClickListener(this);
}
/**
* 馬上開始回撥載入更多了,這裡應該顯示進度條。
*/
@Override
public void onLoading() {
setVisibility(VISIBLE);
mLoadingView.setVisibility(VISIBLE);
mTvMessage.setVisibility(VISIBLE);
mTvMessage.setText("正在努力載入,請稍後");
}
/**
* 載入更多完成了。
*
* @param dataEmpty 是否請求到空資料。
* @param hasMore 是否還有更多資料等待請求。
*/
@Override
public void onLoadFinish(boolean dataEmpty, boolean hasMore) {
if (!hasMore) {
setVisibility(VISIBLE);
if (dataEmpty) {
mLoadingView.setVisibility(GONE);
mTvMessage.setVisibility(VISIBLE);
mTvMessage.setText("暫時沒有資料");
} else {
mLoadingView.setVisibility(GONE);
mTvMessage.setVisibility(VISIBLE);
mTvMessage.setText("沒有更多資料啦");
}
} else {
setVisibility(INVISIBLE);
}
}
/**
* 呼叫了setAutoLoadMore(false)後,在需要載入更多的時候,這個方法會被呼叫,並傳入載入更多的listener。
*/
@Override
public void onWaitToLoadMore(SwipeMenuRecyclerView.LoadMoreListener loadMoreListener) {
this.mLoadMoreListener = loadMoreListener;
setVisibility(VISIBLE);
mLoadingView.setVisibility(GONE);
mTvMessage.setVisibility(VISIBLE);
mTvMessage.setText("點我載入更多");
}
/**
* 載入出錯啦,下面的錯誤碼和錯誤資訊二選一。
*
* @param errorCode 錯誤碼。
* @param errorMessage 錯誤資訊。
*/
@Override
public void onLoadError(int errorCode, String errorMessage) {
setVisibility(VISIBLE);
mLoadingView.setVisibility(GONE);
mTvMessage.setVisibility(VISIBLE);
// 這裡要不直接設定錯誤資訊,要不根據errorCode動態設定錯誤資料。
mTvMessage.setText(errorMessage);
}
/**
* 非自動載入更多時mLoadMoreListener才不為空。
*/
@Override
public void onClick(View v) {
if (mLoadMoreListener != null) mLoadMoreListener.onLoadMore();
}
}
}
相關文章
- Flutter 下拉重新整理上拉載入更多Flutter
- HarmonyOS 下拉重新整理 上拉載入更多 第二種實現方式
- Flutter listview下拉重新整理 上拉載入更多FlutterView
- Flutter下拉重新整理,上拉載入更多資料Flutter
- 載入更多 功能的實現
- Movable-view實現列表的下拉重新整理上拉載入View
- 如何實現上拉載入,下拉重新整理?
- Flutter 實現下拉重新整理&上拉載入Flutter
- Flutter ListView封裝,下拉重新整理、上拉載入更多FlutterView封裝
- 移動端用下拉重新整理的方式實現上拉載入
- 實現移動端上拉載入和下拉重新整理的vue外掛(mescroll.js)VueJS
- 微信開發之下拉重新整理上拉載入更多
- Flutter 入門與實戰(六):給列表增加下拉重新整理和上滑載入更多功能Flutter
- Flutter入門進階之旅(十五)ListView下拉重新整理&上拉載入更多FlutterView
- flutter實戰4:新聞列表的懶載入和下拉手勢重新整理Flutter
- js實現 web頁面的滾動條下拉時載入更多JSWeb
- 移動端上拉載入和下拉重新整理的vue外掛Vue
- vue 實現上拉載入下拉重新整理(思路賊清晰)Vue
- H5下拉重新整理和上拉載入實現原理淺析H5
- Flutter 開發從 0 到 1(四)ListView 下拉載入和載入更多FlutterView
- 【微信小程式】scroll-view 的上拉載入和下拉重新整理微信小程式View
- flutter - RefreshIndicator實現下拉重新整理、上拉載入 | 掘金技術徵文FlutterIndicator
- 小程式 分屏載入&下拉重新整理
- Flutter——下拉重新整理,上拉載入Flutter
- @ComponentScan註解的實現,Spring掃描包的過程Spring
- uni-app | 上拉載入和下拉重新整理探索APP
- java類的載入過程Java
- 整理類載入的過程
- 類的載入過程概述
- 搭建自己的直播平臺,RecycleView下拉重新整理,上拉載入View
- android開發(3):列表listview的實現 | 下拉重新整理AndroidView
- 上拉載入下拉重新整理瞭解下
- flutter - listView 下拉重新整理 上拉載入FlutterView
- 【譯】更多關於漸進式圖片載入的實現
- Vue完美記住滾動條和實現下拉載入Vue
- Flutter之封裝一個下拉重新整理上拉載入的listviewFlutter封裝View
- springboot引導上下文載入過程和配置載入過程Spring Boot
- recyclerView的側拉效果。上拉載入。下拉重新整理,點選事件等等View事件