我刚开始使用ItemDecoration.我试图在由StaggeredGridLayoutManager管理的两列RecyclerView中间实现一个分隔符.
这是我的ItemDecoration代码:
public class LobbyItemDecoration extends RecyclerView.ItemDecoration { private int margin; private Drawable drawable; public LobbyItemDecoration(int margin,Drawable drawable){ this.margin = margin; this.drawable = drawable; } @Override public void getItemOffsets(Rect outRect,View view,RecyclerView parent,RecyclerView.State state) { super.getItemOffsets(outRect,view,parent,state); int position = parent.getChildAdapterPosition(view); StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams)view .getLayoutParams(); int spanIndex = lp.getSpanIndex(); if(position >= 0){ if (position < ((LobiAdapter)parent.getAdapter()).getmDataset().size()){ if(spanIndex == 1){ outRect.left = margin; ((LobiAdapter)parent.getAdapter()).getmDataset().get(position).left = false; } else { outRect.right = margin; ((LobiAdapter)parent.getAdapter()).getmDataset().get(position).left = true; } outRect.bottom = margin; } } } @Override public void onDrawOver(Canvas c,RecyclerView.State state) { if (drawable == null) { super.onDrawOver(c,state);return; } if(parent.getItemAnimator() != null && parent.getItemAnimator().isRunning()) { return; } final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i=1; i < childCount; i++) { final View child = parent.getChildAt(i); StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams)child .getLayoutParams(); int spanIndex = lp.getSpanIndex(); int size = drawable.getIntrinsicWidth(); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int ty = (int)(child.getTranslationY() + 0.5f); final int tx = (int)(child.getTranslationX() + 0.5f); final int leftIndex1 = child.getLeft() - (margin * 4 / 3) - tx; final int rightIndex1 = child.getLeft() - (margin * 2 / 3) - tx; final int leftIndex0 = child.getRight() + (margin * 2 / 3) + tx; final int rightIndex0 = child.getRight() + (margin * 4 / 3) + tx; if(spanIndex == 1){ // drawable.setBounds(100,top,5,bottom); drawable.setBounds(leftIndex1,rightIndex1,bottom); drawable.draw(c); } else { drawable.setBounds(leftIndex0,rightIndex0,bottom); drawable.draw(c); // drawable.setBounds(5,100,bottom); } } } }
问题是标题所说,每当我加载新项目或滚动时,装饰有时会消失或放错地方.我的意思是,实际上已经消失了,直到我向下滚动或向上回收视图才会消失.
错误的意思是,当我向下滚动,并且加载ViewHolder在左列时,分隔符“粘住”到左列.如果加载ViewHolder在右列中,则表示正常.
以防万一:我使用ViewHolder作为进度指示器,通过添加一个空项并在getItemViewType()中检查它,然后在从服务器完成加载后将其删除.
这是我添加的方式:
for (PostModel postModel : dataSet) { this.mDataset.add(postModel); notifyItemInserted(mDataset.size() - 1); }
解决方法
StaggeredGridLayoutManager是错误的.对我来说,这有助于:
diffResult.dispatchUpdatesTo(this); recyclerView.postDelayed(() -> { layoutManager.invalidateSpanAssignments(); // to fix first item in second column issue recyclerView.invalidateItemDecorations(); // to fix wrong spacing },50);