先上效果嘛?再讲遇到的问题
但在代码中,如果不加一行一个行分割器,就无法进下拉刷新。(PS:这个问题排查了两天,一直在找出现问题的地方,最后是无意发现的,项目中的代码里面没有加装饰器类。哭了很久啊)
// 初始化商品类标签
mRecyclerView = (MenuRecyclerView) container.findViewById(R.id.recycler_view);
LinearLayoutManager manager = new LinearLayoutManager(container.getContext());
manager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setOnRefreshViewListener(this);
// 这一行很关键,如果不加上去,就无法进行下拉刷新等操作
mRecyclerView.addItemDecoration(new DividerItemDecoration(container.getContext(), DividerItemDecoration.VERTICAL));
// 增加一个空的界面
View emptyView = container.findViewById(R.id.layout_empty);
mRecyclerView.setEmptyView(emptyView);
TextView textView = (TextView) emptyView.findViewById(R.id.text_empty);
textView.setText("暂无数据");
textView.setTextColor(getResources().getColor(R.color.gray_label));
// 绑定数据
mAdapter = new MessagePeopleAdapter(container.getContext(), data, true);
mAdapter.setOnItemClickListener(this);
mAdapter.setOnMenuItemClickListener(this);
mRecyclerView.setAdapter(mAdapter);
运行结果如下:
// 滑动 header
private void moveHeader(MotionEvent e){
int x = (int) e.getX();
int y = (int) e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
isOnTouching = true;
break;
case MotionEvent.ACTION_MOVE:
//判断是否滑动到了头部
Log.e("TAG", "判断是否滑动到了头部:"+canScrollVertically(-1));
if (!canScrollVertically(-1)) {
int dy = lastY - y;
int dx = lastX - x;
if (Math.abs(dy) > Math.abs(dx)) {
isRefresh = true;
changeHeight(dy);
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
isRefresh = false;
isOnTouching = false;
if (mState == STATE_READY) {
onStatusChange(STATE_REFRESHING);
}
autoSize();
break;
}
lastX = x;
lastY = y;
}
正确结果

如果不加分割装饰器类的话,就一直表示未滑动到顶部。
最后查看了一下,源代码:
其中
// 这一行很关键,如果不加上去,就无法进行下拉刷新等操作 mRecyclerView.addItemDecoration(new DividerItemDecoration(container.getContext(), DividerItemDecoration.VERTICAL));
主要调用到了下面这个函数 isComputingLayout 返回true表示lockdown锁定状态下,adapter的更新将不再更新RecylerView的layout大小。不太了解的情况下,使用该方法,很坑的
/**
* Returns whether RecyclerView is currently computing a layout.
* <p>
* If this method returns true, it means that RecyclerView is in a lockdown state and any
* attempt to update adapter contents will result in an exception because adapter contents
* cannot be changed while RecyclerView is trying to compute the layout.
* <p>
* It is very unlikely that your code will be running during this state as it is
* called by the framework when a layout traversal happens or RecyclerView starts to scroll
* in response to system events (touch, accessibility etc).
* <p>
* This case may happen if you have some custom logic to change adapter contents in
* response to a View callback (e.g. focus change callback) which might be triggered during a
* layout calculation. In these cases, you should just postpone the change using a Handler or a
* similar mechanism.
*
* @return <code>true</code> if RecyclerView is currently computing a layout, <code>false</code>
* otherwise
*/
public boolean isComputingLayout() {
return mLayoutOrScrollCounter > 0;
}