You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView加载图片调整宽高触发Bitmap.getHeight空指针报错如何解决

错误原因排查

你触发空指针的核心问题是:

  • 类成员变量Bitmap bm仅声明未初始化,默认值为null,你在声明后直接调用bm.getHeight()、bm.getWidth()读取宽高,此时bm还没有被赋值,必然抛出空指针异常。
    同时你的代码还存在2个逻辑问题:
  • 你先读取bm宽高赋值给布局参数,后续又直接把布局参数的宽高硬编码为WRAP_CONTENT和MATCH_PARENT,前面读取Bitmap宽高的代码完全多余,没有任何实际作用
  • 你当前修改的是Fragment根布局里的单个ShapeableImageView的参数,要适配RecyclerView列表里的图片宽高,逻辑应该写在RecyclerView适配器的绑定逻辑中,而不是Fragment的初始化方法里
可行解决方案

第一步:清理Fragment中的无效代码

调整后的Fragment_Search.java参考如下:

ShapeableImageView siv;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_search, container, false);
    requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    postRecyclerView = view.findViewById(R.id.postRecyclerView);
    // 仅当这个siv是Fragment根布局的控件时保留这段配置,是列表项控件的话直接删除即可
    siv = view.findViewById(R.id.imageView);
    ViewGroup.LayoutParams params = siv.getLayoutParams();
    params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
    siv.setLayoutParams(params); // 必须调用setLayoutParams配置才会生效,原有代码漏了这行
    // 初始化瀑布流布局
    postRecyclerView.setLayoutManager(
            new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
    );
    getData();
    mUploads = new ArrayList<>();
    postsAdapter = new PostAdapter_Search(getContext(), mUploads);
    postRecyclerView.setAdapter(postsAdapter);
    return view;
}

第二步:配置RecyclerView列表项的图片自适应

方式1:布局直接配置(优先推荐)

在列表项的布局XML中,给图片控件增加adjustViewBounds属性,即可自动按图片比例适配宽高,不需要额外写代码:

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/item_post_img"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="centerCrop" />

配合Glide等图片加载框架直接加载即可,框架会自动适配控件大小,还可以增加占位图避免滑动时布局跳动:

// 写在PostAdapter_Search的onBindViewHolder方法中
Glide.with(context)
    .load(upload.getImageUrl())
    .placeholder(R.drawable.your_placeholder)
    .into(holder.itemPostImg);

方式2:手动读取Bitmap宽高配置

如果确实需要手动计算宽高再设置,必须等Bitmap加载完成后再调用读取宽高的方法,参考逻辑(以Glide为例):

// 写在PostAdapter_Search的onBindViewHolder方法中
Glide.with(context)
    .asBitmap()
    .load(upload.getImageUrl())
    .into(new CustomTarget<Bitmap>() {
        @Override
        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
            // 此时Bitmap已经加载完成,不会为空
            int imgWidth = resource.getWidth();
            int imgHeight = resource.getHeight();
            ViewGroup.LayoutParams params = holder.itemPostImg.getLayoutParams();
            params.width = ViewGroup.LayoutParams.MATCH_PARENT;
            // 按宽度比例计算高度,保证图片不变形
            params.height = (int) ((float) params.width / imgWidth * imgHeight);
            holder.itemPostImg.setLayoutParams(params);
            holder.itemPostImg.setImageBitmap(resource);
        }

        @Override
        public void onLoadCleared(@Nullable Drawable placeholder) {
        }
    });

内容的提问来源于stack exchange,提问作者user16125085

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 02:36:09