android RecycleViewは、ドロップダウンリフレッシュとアップロードを実現しました。


Androidのドロップダウンリフレッシュ、アップロード機能、ページをめくる時は第1ページから現在のページまでの内容が表示され、現在表示されているのは現在のページの内容です。
1.PulRefresh RecyclerView.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.Punsh ListActivity.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 Punnish Adapter.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ドロップダウンアップロード効果』まで整理されました。みなさんの研究を歓迎します。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。