Android RecyclerView适配器中ImageView高度为0无法显示问题
问题分析与解决方案
问题原因
当你给ImageView设置android:layout_height="wrap_content"和android:adjustViewBounds="true"时,RecyclerView在初始化item布局阶段,因为还未加载图片,ImageView没有可参考的尺寸,导致item被测量出高度为0。而RecyclerView会缓存item的测量高度,即使后续Glide加载完图片,ImageView高度发生变化,RecyclerView也不会主动重新测量item高度,最终图片无法显示。
解决方案
方案1:添加缩放类型+加载完成后强制重布局
首先给布局中的ImageView添加缩放类型,确保adjustViewBounds能正常生效:
<ImageView android:id="@+id/img" android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="fitCenter" /> <!-- 添加缩放类型属性 -->
然后在Glide加载时添加监听,图片加载完成后触发item重新布局:
@Override public void onBindViewHolder(MyViewHolder viewHolder, int position) { Blog_items item = list.get(position); // 注意:这里要取当前item对应的图片地址,避免使用固定值 String imgUrl = ctx.getString(R.string.url) + "NewsPictures/" + item.getImgUrl(); Glide.with(ctx) .load(imgUrl) .listener(new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { // 触发item重新布局,让RecyclerView重新计算高度 viewHolder.itemView.requestLayout(); return false; } }) .into(viewHolder.img); }
方案2:手动计算并设置ImageView高度
如果方案1不生效,可以通过Glide的自定义Target获取图片原始尺寸,按比例计算ImageView的高度(适配屏幕宽度):
@Override public void onBindViewHolder(MyViewHolder viewHolder, int position) { Blog_items item = list.get(position); String imgUrl = ctx.getString(R.string.url) + "NewsPictures/" + item.getImgUrl(); Glide.with(ctx) .load(imgUrl) .into(new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { viewHolder.img.setImageDrawable(resource); // 获取图片原始宽高 int intrinsicWidth = resource.getIntrinsicWidth(); int intrinsicHeight = resource.getIntrinsicHeight(); if (intrinsicWidth <= 0 || intrinsicHeight <= 0) return; // 计算ImageView可用宽度(屏幕宽度减去CardView的左右margin) DisplayMetrics metrics = ctx.getResources().getDisplayMetrics(); int screenWidth = metrics.widthPixels; // 直接计算5dp对应的像素值 int cardMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, metrics); int availableWidth = screenWidth - 2 * cardMargin; // 按比例计算ImageView高度 float ratio = (float) intrinsicHeight / intrinsicWidth; int calculatedHeight = (int) (availableWidth * ratio); // 设置ImageView高度 ViewGroup.LayoutParams params = viewHolder.img.getLayoutParams(); params.height = calculatedHeight; viewHolder.img.setLayoutParams(params); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { } }); }
注意点
- 确保加载图片时使用当前item对应的图片地址,避免所有item加载同一张图。
- 两种方案都能实现图片高度自适应,可根据实际测试效果选择。
内容的提问来源于stack exchange,提问作者Navid Abutorab
相关产品推荐
相关产品推荐

