android RecycleView實現下拉重新整理和上拉載入
阿新 • • 發佈:2020-06-23
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下拉重新整理上拉載入效果》,歡迎大家學習研究。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。