记录一下,瀑布流错乱问题
问题
主要是在Item中图片并不会固定宽高,而是在加载后再去计算的,所以在复用子View时不断的进行重新排版,导致最后展示时出现了偏差,也就是错乱留白。
解决办法
解决办法也就是针对布局和留白去进行处理,总的来说这几句话:在布局时先计算布局尺寸,在滚到顶部时处理留白,在加载数据时注意刷新(刷新会重置布局和保存的尺寸)。
以下解决方法可重叠使用。
-
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
- 按照图片的宽高,在界面加载前,先设置ImageView的布局
if (items.get(position).getHeight() > 0) { ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams(); layoutParams.height = items.get(position).getHeight(); } Glide.with(context).load(items.get(position).getImg_url()).asBitmap() .into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { if (position != RecyclerView.NO_POSITION) { if (items.get(position).getHeight() <= 0) { int imageWidth = resource.getWidth(); int imageHeight = resource.getHeight(); int width = (ScreenUtils.getScreenWidth(context) - DensityUtil.dip2px(context, 30)) / 2; //宽度固定,然后根据原始宽高比得到此固定宽度需要的高度 int height = width * imageHeight / imageWidth; LogUtils.e("设置的高:" + height); items.get(position).setHeight(height); ViewGroup.LayoutParams para = item_note_img_iv.getLayoutParams(); para.height = height; para.width = width; } imageView.setImageBitmap(resource); } } });
- 实际上解决错乱与留白的问题 主要原因在于加载更多数据之后 使用的是notifyDataSetChanged()该方法将刷新一整个Recycleview的数据;所以解决方案将 notifyDataSetChanged()替换成 notifyItemRangeInserted(int positionStart, int itemCount)进行新增数据局部刷新。
- 第四种方法就是在滚动到顶部时,进行留白处理
//防止顶部空白 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //2为列数 int[] first = new int[2]; layoutManager.findFirstCompletelyVisibleItemPositions(first); if (newState == RecyclerView.SCROLL_STATE_IDLE ){ if (first[0] == 1 || first[1] == 1) { layoutManager.invalidateSpanAssignments(); } } } });
-
还有一种方法说是重写getItemViewType,但我没试过
@Override public int getItemViewType(int position) { return Math.round((float) App.SCREEN_WIDTH / (float) mList.get(position).getHeight() * 10f); }