1.下拉刷新
比较简单
2.上拉加载
思路:
首先,需要判断用户的手势是否是下拉刷新的手势;
使用setOnTouchListener()的问题及其原因:
问题:接收不到ACTION_DWON事件,
场景:当RecyclerView为match_parent时,且内容显示为完全填充满,由于item中设置了触摸监听(正常按下,长按)
示例代码:
private boolean shouldExecute = false; // 是否是上拉 private float startY = 0; recyclerView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 这里的代码可以忽略 startY = event.getY(); VrvLog.i("xljx", "lastY:" + startY); break; case MotionEvent.ACTION_MOVE: if(startY <= 0){// 如果需要更精细的判断,例如:当前触摸点的Y轴距离只能越来越来小 startY = event.getY(); } break; case MotionEvent.ACTION_UP: VrvLog.i("xljx","event.getY():" + event.getY() + " lastY:" + startY); if (event.getY() - startY < 0) { shouldExecute = true; } else { shouldExecute = false; } startY = 0;// reset data break; default: break; } return false; } });
其次,检测当前RecyclerView显示内容是否适合下拉刷新的场景;
实际使用中包括两个部分,一个是RecyclerView的最后一个条目是否已经显示(并处于RecyclerView的底部---具体也要区分场景,后面论述),
另一种情况是当前是否是请求状态,即已经调用了相关方法并在请求数据(一般有这种需求的情况),或者当前已经确定没有可请求的数据。
// 上拉加载更多处理 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { // super.onScrollStateChanged(recyclerView, newState); VrvLog.i("xljx", "newState:" + newState); if (!shouldExecute) { // 1.判断手势 return; } if (fileLoading || imgLoading) { // 2.是否正在请求文件或者图片 return; } RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int visibleItemCount = layoutManager.getChildCount(); // 获取可视化的item数量 int totalItemCount = layoutManager.getItemCount(); // adpter中数据的总数 // 前提条件是LayoutManager是LinearLayoutManager类型或者子类 int lastVisibleItemPosition = ((LinearLayoutManager) layoutManager) .findLastVisibleItemPosition(); // todo: 查看源码实现 // public static final int SCROLL_STATE_IDLE = 0; // public static final int SCROLL_STATE_DRAGGING = 1; // public static final int SCROLL_STATE_SETTLING = 2; if ((visibleItemCount > 0 && newState == RecyclerView.SCROLL_STATE_IDLE && (lastVisibleItemPosition) >= totalItemCount - 1)) { // 位于recyclerView最底部 if (hasFile || hasImg) { // 是否能够加载更多的数据 VrvLog.i(TAG, "加载更多"); getFileList(REQUEST_ONE_COUNT); } else { ToastUtil.showShort(R.string.file_load_tips); } } shouldExecute = false; } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {} });
图1
private RequestCallBack<List<FileInfo>, Void, Void> fileRequestCallBack = new RequestCallBack<List<FileInfo>, Void, Void>() { @Override public void handleSuccess(List<FileInfo> fileInfos, Void aVoid, Void aVoid2) { fileLoading = false; if (adapter != null && fileInfos != null && fileInfos.size() > 0) { if (fileInfos.size() < REQUEST_ONE_COUNT) { // REQUEST_ONE_COUNT = 30 hasFile = false; } else { hasFile = true; } dataSet.addAll(dataSet.size(), fileInfos); adapter.notifyDataSetChanged(); msgFileBeginID = fileInfos.get(fileInfos.size() - 1).getFileID() - 1; } else { hasFile = false; ToastUtil.showShort(R.string.file_load_tips); } } @Override public void handleFailure(int code, String message) { super.handleFailure(code, message); fileLoading = false; } }; /** * 获取个人/群的文件和图片数据 */ private void getFileList(int offSet) { // 获取文件 if (hasFile) { if (!fileLoading) { if (ChatMsgApi.isGroup(id)) { fileLoading = true; RequestHelper.getGroupFileList(id, msgFileBeginID, offSet, (byte) 0, fileRequestCallBack); } else if (ChatMsgApi.isUser(id)) { fileLoading = true; RequestHelper.getFileList(id, msgFileBeginID, offSet, (byte) 0, fileRequestCallBack); } } } else { ToastUtil.showShort(R.string.file_load_tips); } // 获取图片, 只需要查询一次即可 if (hasImg) { if (!imgLoading) { imgLoading = true; RequestHelper.getImgMsg(id, new RequestCallBack<List<ChatMsg>, Void, Void>() { @Override public void handleSuccess(List<ChatMsg> chatMsgs, Void aVoid, Void aVoid2) { imgLoading = false; if (adapter != null && chatMsgs != null && chatMsgs.size() > 0) { hasImg = false; // important dataSet.addAll(dataSet.size(), chatMsgs); adapter.notifyDataSetChanged(); } else { hasImg = false; } } @Override public void handleFailure(int code, String message) { super.handleFailure(code, message); imgLoading = false; } }); } } }
或者使用开源仓库:
https://github.com/scwang90/SmartRefreshLayout
没有帐号? 立即注册