android RecycleView实现下拉刷新和上拉加载

时间:2022-07-27
本文章向大家介绍android RecycleView实现下拉刷新和上拉加载,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

android的下拉刷新,上拉加载功能,翻页时显示从第1页开始到当前页面的内容,并且当前显示的是当前页的内容;

1.PullRefreshRecyclerView.java : 翻页控件

public class PullRefreshRecyclerView extends LinearLayout implements SwipeRefreshLayout.OnRefreshListener, View.OnTouchListener {
private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView recyclerView;
private LinearLayout footerView;
private OnPullRefreshListener listener;
//是否正在刷新
private boolean isRefreshing = false;
//是否正在加载
private boolean isLoading = false;
//是否有更多数据
private boolean hasMore = false;
public PullRefreshRecyclerView(Context context) {
this(context, null);
}
public PullRefreshRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
initListener();
init();
}
private void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.pull_recycler_layout, this, true);
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
recyclerView = findViewById(R.id.recyclerView);
footerView = findViewById(R.id.footerView);
}
private void initListener() {
swipeRefreshLayout.setOnRefreshListener(this);
recyclerView.addOnScrollListener(new PullableScroll());
//防止滚动的时候,滑动View
recyclerView.setOnTouchListener(this);
}
private void init() {
swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_dark,
android.R.color.holo_blue_dark,
android.R.color.holo_orange_dark);
//隐藏垂直滚动条
recyclerView.setVerticalScrollBarEnabled(true);
//item高度固定时,设置该选项提高性能
recyclerView.setHasFixedSize(true);
//设置item动画效果
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
public void setHasFixedSize(boolean hasFixedSize) {
recyclerView.setHasFixedSize(hasFixedSize);
}
public void setItemAnimator(RecyclerView.ItemAnimator animator) {
recyclerView.setItemAnimator(animator);
}
public void setLayoutManager(RecyclerView.LayoutManager layout) {
recyclerView.setLayoutManager(layout);
}
public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
recyclerView.setVerticalScrollBarEnabled(verticalScrollBarEnabled);
}
public void addItemDecoration(RecyclerView.ItemDecoration decor) {
recyclerView.addItemDecoration(decor);
}
public void setAdapter(RecyclerView.Adapter adapter) {
recyclerView.setAdapter(adapter);
}
/**
* 设置监听下拉或上拉的事件
*
* @param listener
*/
public void setOnPullRefreshListener(OnPullRefreshListener listener) {
this.listener = listener;
}
/**
* 设置是否有更多数据
*
* @param hasMore
*/
public void setHasMore(boolean hasMore) {
this.hasMore = hasMore;
}
/**
* 滚动到顶部
*/
public void scrollToTop() {
recyclerView.scrollToPosition(0);
}
/**
* 正在刷新
*/
@Override
public void onRefresh() {
isRefreshing = true;
if (listener != null) {
listener.onRefresh();
}
}
/**
* 设置是否允许下拉
*
* @param enable
*/
public void setRefreshEnable(boolean enable) {
swipeRefreshLayout.setEnabled(enable);
}
/**
* 滚动时判断能否能刷新
*
* @return
*/
private boolean isRefreshEnable() {
return !isRefreshing && !isLoading;
}
/**
* 正在加载更多
*/
public void doLoadMore() {
if (!isLoading && hasMore && !isRefreshing) {
footerView.setVisibility(View.VISIBLE);
isLoading = true;
//禁止下拉
setRefreshEnable(false);
if (listener != null) {
listener.onLoadMore();
}
}
}
/**
* 刷新或加载完成
*/
public void refreshOrLoadComplete() {
isRefreshing = false;
swipeRefreshLayout.setRefreshing(false);
isLoading = false;
footerView.setVisibility(View.GONE);
//允许下拉
this.setEnabled(true);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return isRefreshing || isLoading;
}
public interface OnPullRefreshListener {
/**
* 刷新操作
*/
void onRefresh();
/**
* 加载操作
*/
void onLoadMore();
}
/**
* 监听RecycleView滑动底部或顶部
*/
class PullableScroll extends RecyclerView.OnScrollListener {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int lastVisibleItem = 0;
int firstVisibleItem = 0;
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
int totalItemCount = layoutManager.getItemCount();
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
// since may lead to the final item has more than one StaggeredGridLayoutManager the particularity of the so here that is an array
// this array into an array of position and then take the maximum value that is the last show the position value
int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
lastVisibleItem = findMax(lastPositions);
firstVisibleItem = staggeredGridLayoutManager.findFirstVisibleItemPositions(lastPositions)[0];
}
pullRefreshEnable(firstVisibleItem, totalItemCount);
if (isSlideToBottom(recyclerView)) {
loadMore(dx, dy, lastVisibleItem, totalItemCount);
}
}
private int findMax(int[] lastPositions) {
int max = lastPositions[0];
for (int value : lastPositions) {
if (value   max) {
max = value;
}
}
return max;
}
}
/**
* 判断是否滑动到底部
*
* @param recyclerView
* @return
*/
public boolean isSlideToBottom(RecyclerView recyclerView) {
if (recyclerView == null) {
return false;
}
if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset()
= recyclerView.computeVerticalScrollRange()) {
return true;
}
return false;
}
private void loadMore(int dx, int dy, int lastVisibleItem, int totalItemCount) {
//滚动到底部时且有更多数据能够上拉加载
if (lastVisibleItem  = totalItemCount - 1 && (dx   0 || dy   0)) {
doLoadMore();
}
}
private void pullRefreshEnable(int firstVisibleItem, int totalItemCount) {
//滚动到顶部时能够下拉刷新
if (firstVisibleItem == 0 || totalItemCount == 0) {
if (isRefreshEnable()) {
//允许下拉
setRefreshEnable(true);
}
} else {
//禁止下拉
setRefreshEnable(false);
}
}
}

2.PunishListActivity.java: 调用

@Route(path = Page.ACTIVITY_PUNISH_LIST)
public class PunishListActivity extends BaseActivity implements View.OnClickListener, PullRefreshRecyclerView.OnPullRefreshListener {
private static final String TAG = "PunishListActivity";
private List<PunishBean  punishBeans = new ArrayList< ();
private Context mContext;
private EditText et_punish_searchName;
private ImageView iv_search;
private PullRefreshRecyclerView prr_punish;
private String officeName = "";
private int pageNo = 1;
private boolean isLastPage = false;
private PunishAdapter punishAdapter;
@Override
public void onBeforeSetContentView() {
StatusBarUtil.translucent(this, ContextCompat.getColor(this, R.color.color_0a5fb6));
}
@Override
public int getLayoutResID() {
return R.layout.activity_punish_list;
}
@Override
protected CharSequence setActionBarTitle() {
return "行政处罚";
}
@Nullable
@Override
public AppBarConfig getAppBarConfig() {
return mAppBarCompat;
}
@Override
public int setActionBarRightVisibility() {
return View.VISIBLE;
}
@Override
public CharSequence setActionBarRightText() {
return "添加";
}
public void onResume(){
super.onResume();
getPunishList("");
}
@Override
public void initContentView(@Nullable Bundle savedInstanceState) {
mContext = PunishListActivity.this;
et_punish_searchName = findViewById(R.id.et_punish_searchName);
iv_search = findViewById(R.id.iv_search);
iv_search.setOnClickListener(this);
prr_punish = findViewById(R.id.prr_punish);
prr_punish.setOnPullRefreshListener(this);
prr_punish.setHasMore(true);
}
@Override
public void initData(@Nullable Bundle savedInstanceState) {
punishAdapter = new PunishAdapter(mContext,punishBeans);
LinearLayoutManager manager = new LinearLayoutManager(mContext);
manager.setOrientation(RecyclerView.VERTICAL);
prr_punish.setLayoutManager(manager);
prr_punish.setAdapter(punishAdapter);
// getPunishList();
}
private void getPunishList(String officeName){
HashMap<String, Object  baseParam = WebFrontUtil.getBaseParam();
baseParam.put("pageNo", pageNo);
baseParam.put("pageSize", 10);
baseParam.put("officeName", officeName);
OkHttpUtil.post(TAG, WebApi.PUNISH_LIST_URL, baseParam, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
hideWaitDialog();
Log.d(TAG,""+e);
}
@Override
public void onResponse(String response, int id) {
Log.d(TAG,"response==="+response);
try {
JSONObject object = new JSONObject(response);
hideWaitDialog();
if ((int)object.get("code") == 200) {
JSONObject object1 = object.getJSONObject("data");
PunishBeanList punishBeanList = new Gson().fromJson(object1.toString(),PunishBeanList.class);
Log.d(TAG,"response==="+punishBeanList.getList().size());
if (pageNo == 1) {
punishBeans.clear();
}
if (punishBeanList.getList() != null && punishBeanList.getList().size() != 0) {
List<PunishBean  addPunishs = new ArrayList< ();
addPunishs = punishBeanList.getList();
if (punishBeans.size()   0) {
punishBeans.addAll(addPunishs);
punishAdapter.addMoreData(addPunishs);
} else {
punishBeans = addPunishs;
punishAdapter.setData(addPunishs);
}
if (punishBeanList.isLastPage()) {
isLastPage = true;
Log.e(TAG,"isLastPage = true ");
}else {
isLastPage = false;
Log.e(TAG,"isLastPage = false ");
}
}
} else {
Toast.makeText(mContext,object.get("message").toString(),Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void actionBarRightOnClick() {
ARouter.getInstance().build(Page.ACTIVITY_PUNISH_ADD).navigation();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_search:
showWaitDialog();
officeName = et_punish_searchName.getText().toString();
pageNo = 1;
isLastPage = false;
getPunishList(officeName);
break;
}
}
@Override
public void onRefresh() {
prr_punish.refreshOrLoadComplete();
pageNo = 1;
getPunishList(officeName);
prr_punish.setRefreshEnable(true);
}
@Override
public void onLoadMore() {
Log.d(TAG,"onLoadMore===================");
prr_punish.refreshOrLoadComplete();
if (isLastPage) {
prr_punish.setRefreshEnable(false);
} else {
pageNo += 1;
getPunishList(officeName);
}
}
}

3.PunishAdapter.java

public class PunishAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder  {
private Context mContext;
private List<PunishBean  punishList;
public PunishAdapter(Context mContext, List<PunishBean  punishList) {
this.mContext = mContext;
this.punishList = punishList;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.punish_item,parent,false);
PunishHolder punishHolder = new PunishHolder(view);
return punishHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
PunishBean punishBean = punishList.get(position);
PunishHolder punishHolder = (PunishHolder) holder;
punishHolder.tv_punishName.setText(punishBean.getOfficeName());
punishHolder.tv_faren.setText(punishBean.getLegalPerson());
punishHolder.tv_punishMode.setText(punishBean.getPunishWay());
punishHolder.tv_punishReason.setText(punishBean.getReason());
punishHolder.tv_punishTime.setText(punishBean.getUpdateTime());
punishHolder.tv_punishDesc.setText(punishBean.getRemarks());
punishHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putSerializable("punishDetail",punishBean);
ARouter.getInstance().build(Page.ACTIVITY_PUNISH_DETAIL).with(bundle).navigation();
}
});
}
/*
* 向列表尾部添加数据
* */
public void addMoreData(List<PunishBean  list) {
int oldSize = punishList.size();
if (list != null && list.size()   0) {
punishList.addAll(punishList.size(), list);
notifyItemRangeInserted(oldSize, list.size());
}
}
/*
* 填充新数据
* */
public void setData(List<PunishBean  data) {
if (data != null && data.size()   0) {
punishList.clear();
punishList.addAll(data);
notifyDataSetChanged();
}
}
@Override
public int getItemCount() {
return punishList==null? 0:punishList.size();
}
class PunishHolder extends RecyclerView.ViewHolder {
private TextView tv_punishName,tv_faren,tv_punishMode,tv_punishReason,tv_punishTime,tv_punishDesc;
public PunishHolder(@NonNull View itemView) {
super(itemView);
tv_punishName = itemView.findViewById(R.id.tv_punishName);
tv_faren = itemView.findViewById(R.id.tv_faren);
tv_punishMode = itemView.findViewById(R.id.tv_punishMode);
tv_punishReason = itemView.findViewById(R.id.tv_punishReason);
tv_punishTime = itemView.findViewById(R.id.tv_punishTime);
tv_punishDesc = itemView.findViewById(R.id.tv_punishDesc);
}
}
}

4.布局文件:

<?xml version="1.0" encoding="utf-8"? 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:layout_margin="@dimen/px40"
android:background="@color/color_ffffff"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".modules.punish.PunishListActivity" 
<RelativeLayout
android:id="@+id/rl_punish_search"
android:layout_width="match_parent"
android:layout_marginTop="@dimen/px20"
android:layout_height="103px"
android:background="@drawable/bg_radius_blue" 
<EditText
android:id="@+id/et_punish_searchName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/px44"
android:layout_marginEnd="@dimen/px110"
android:background="@null"
android:hint="请输入单位名称"
android:inputType="text"
android:textColor="@color/color_hint"
android:textColorHint="@color/color_hint"
android:textSize="@dimen/font_14" / 
<ImageView
android:id="@+id/iv_search"
android:layout_width="@dimen/px54"
android:layout_height="@dimen/px54"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/px50"
android:src="@drawable/icon_text_search" / 
</RelativeLayout 
<com.nmpa.nmpaapp.widget.PullRefreshRecyclerView
android:id="@+id/prr_punish"
android:layout_width="match_parent"
android:layout_height="wrap_content"/ 
</LinearLayout 

本文已经被整理到《Android下拉刷新上拉加载效果》,欢迎大家学习研究。

以上就是本文的全部内容,希望对大家的学习有所帮助。