Android中使用Fresco库的SimpleDraweeView在RecyclerView内加载图片拉伸失真问题求助
问题原因&解决办法
嘿,我来帮你排查这个Fresco在RecyclerView里的显示问题!从你的代码和描述来看,留白区域出现拉伸条纹主要是两个原因导致的,结合Fresco的机制和RecyclerView的复用特性,咱们一步步来解决:
1. 空白区域没设背景,复用item时残留旧内容
你用了CENTER_INSIDE这个缩放类型,图片会保持原比例居中,不会填满整个SimpleDraweeView,这时候空白区域默认是透明的。但RecyclerView的item是循环复用的,之前加载过的图片碎片可能会留在这些空白区域,就形成了你看到的“拉伸条纹”。
另外你还设置了圆角参数RoundingParams,如果没给圆角的空白区域指定填充色,Fresco也可能用透明或者残留内容来填充,雪上加霜。
2. 每次都新建Hierarchy,既浪费内存又容易出状态问题
你在每个item里都新建GenericDraweeHierarchy,这完全没必要——Fresco的Hierarchy是可以复用的,重复创建不仅占内存,还可能因为每个Hierarchy的状态没重置,导致复用item时显示异常。
具体解决步骤
第一步:给空白区域加背景色
修改Hierarchy的构建代码,要么给整个Hierarchy加背景,要么给圆角参数指定填充色,选一个适合你的:
方式A:给Hierarchy设置全局背景
// 选和你的页面背景一致的颜色,比如白色 Drawable bg = new ColorDrawable(ContextCompat.getColor(activity, android.R.color.white)); GenericDraweeHierarchy hierarchy = GenericDraweeHierarchyBuilder.newInstance(activity.getResources()) .setRoundingParams(roundingParams) .setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE) .setBackground(bg) // 关键:用背景色填充空白区域 .setFailureImage(ContextCompat.getDrawable(activity,R.drawable.ic_image_off)) .setProgressBarImage(ContextCompat.getDrawable(activity,R.drawable.animview)) .build();
方式B:给圆角参数设置填充色
RoundingParams roundingParams = RoundingParams.fromCornersRadius(50f); // 给圆角周围的空白区域填色,和页面背景匹配就行 roundingParams.setOverlayColor(ContextCompat.getColor(activity, android.R.color.white));
第二步:复用Hierarchy,别重复创建
把Hierarchy的初始化移到RecyclerView Adapter的构造方法里,全局只用一个,所有item都复用它:
// 在Adapter里定义全局的Hierarchy private GenericDraweeHierarchy reusableHierarchy; // Adapter构造方法里初始化一次 public YourAdapter(Activity activity) { RoundingParams roundingParams = RoundingParams.fromCornersRadius(50f); roundingParams.setOverlayColor(ContextCompat.getColor(activity, android.R.color.white)); reusableHierarchy = GenericDraweeHierarchyBuilder.newInstance(activity.getResources()) .setRoundingParams(roundingParams) .setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE) .setFailureImage(ContextCompat.getDrawable(activity,R.drawable.ic_image_off)) .setProgressBarImage(ContextCompat.getDrawable(activity,R.drawable.animview)) .setBackground(new ColorDrawable(ContextCompat.getColor(activity, android.R.color.white))) .build(); } // 在绑定ViewHolder的时候直接复用 @Override public void onBindViewHolder(YourViewHolder holder, int position) { holder.imageView.setHierarchy(reusableHierarchy); holder.imageView.setImageURI(uri); }
额外提醒:检查SimpleDraweeView的布局
看看item布局里的SimpleDraweeView宽高设置,尽量别用wrap_content(尤其是高度),如果必须用的话,可以给Fresco加个宽高比设置,避免布局异常导致的显示问题。
内容的提问来源于stack exchange,提问作者ghost
相关产品推荐
相关产品推荐

