解决瀑布流过度复用Item导致条目闪烁,跳动,换位问题

方法一、

// 瀑布流布局管理器
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);

// 设置item的间距处理方式
staggeredGridLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
mRecyclerView.setLayoutManager(staggeredGridLayoutManager);

来解释一下方法中的参数

我们有两种方式可以选择
GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
GAP_HANDLING_NONE

1、GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS:当滑动空闲时,也就是 SCROLL_STATE_IDLE 这个状态下时,会去检查 item 之间有没有间隙,如果有就调整 item 的位置,并使用动画的过度效果。

2、GAP_HANDLING_NONE:不去处理这个间隙。

以上方式可以解决 如出现顶部留白或空隙过大现象请继续往下瞅瞅

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        staggeredGridLayoutManager.invalidateSpanAssignments(); //防止第一行到顶部有空白区域
    }
});

但是单纯调这个方法,没什么卵用,而且布局会变得更乱,所以这个方法是在 上面layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE)的基础上,在使用这个东西。

方法二、

提前设置图片控件大小

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    final ImageEntity.ListBean listBean = listBeans.get(position);
    // 获取布局页面的尺寸和密度
    Resources resources = mContext.getResources();
    DisplayMetrics dm = resources.getDisplayMetrics();
    // 设置布局页面的宽度比例
    int width = dm.widthPixels/3;
    // 获取到已知图片的宽高比,通过设置的宽指定高
    int height = (int) (width*(Float.parseFloat(listBean.getHeight())/Float.parseFloat(listBean.getWidth())));
    // 获取到图片的布局
    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) holder.imageView.getLayoutParams();
    // 给图片布局设置 高度
    layoutParams.height = height;
    // 重新给图片设置布局
    holder.imageView.setLayoutParams(layoutParams);
    
    Glide.with(mContext).load(listBeans.get(position).getImg()).into(holder.imageView);

    holder.imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(mContext, ImageActivity.class);
            intent.putExtra("imageSrc",listBean.getImg());
            mContext.startActivity(intent);
        }
    });
}

不知道图片大小.这种情况就需要在 onBindViewHolder 之前设置图片的大小.因为如果在 onBindViewHolder 中使用 Glide 异步的获取图片的大小会导致图片因为没有及时获取高度而出现空白.可以在 setList 处添加,比如这样

public void setData(List<Result> data) {
    mData = data;
    setImageScale();
}

private void setImageScale() {
    for (final Result girlBean : mData) {
        if (girlBean.getScale() == 0) {
            Glide.with(mContext).load(girlBean.getUrl()).into(new SimpleTarget<Drawable>() {
                @Override
                public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                    float scale = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
                    girlBean.setScale(scale);
                    notifyDataSetChanged();
                }
            });
        } else {
            notifyDataSetChanged();
        }
    }
}

在 onBindviewHolder 中:

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    Result result = mData.get(position);

    final ViewGroup.LayoutParams layoutParams = holder.mIv.getLayoutParams();
    layoutParams.width = DisplayUtils.getScreenWidth((Activity) mContext) / 2 - DisplayUtils.dp2px(mContext, 8);
    if (result.getScale() != 0) {
        layoutParams.height = (int) (layoutParams.width / result.getScale());
    }
    holder.mIv.setBackgroundColor(Color.BLUE);

    Glide.with(mContext).load(result.getUrl()).into(holder.mIv);
}

如果实体类中没有Scale 变量,需要添加到要解析的实体类中去,并设置 getter,setter 方法

private float scale;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值