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
相关产品推荐
相关产品推荐

