为什么Android中ImageView的图片仅在联想Android8.1平板上显示为中心点?
问题根因
这个是Android 8.1(API 27)部分联想设备ROM的兼容性问题:原生ImageView.setImageURI()方法仅对应用内资源Uri做了适配,对外部存储、相册返回的Uri解码逻辑存在厂商定制缺陷,大尺寸图片解码失败后会展示极小的默认占位图,最终呈现为中心小点的效果。
可行解决方案
- 方案1:使用成熟图片加载库处理(推荐)
Glide等第三方图片库已经做了全版本ROM的兼容性适配,自动处理Uri解码、尺寸压缩、内存管理,替换原有setImageURI逻辑即可:// 引入Glide依赖后替换原有代码 markerViewModel.getChosenPicture().observe(getViewLifecycleOwner(), uri -> { if (uri != null) { Glide.with(this) .load(uri) .centerCrop() .into(binding.petPicture); petPicture = uri; } }); - 方案2:自行解码Uri为Bitmap后设置
若不想引入第三方依赖,可手动适配Uri解码逻辑,同时做尺寸压缩避免OOM:private void setImageUriToView(Uri uri, ImageView imageView) { try { // 先读取图片尺寸,按需压缩 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; InputStream inputStream = getContentResolver().openInputStream(uri); BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); // 计算压缩比,匹配ImageView尺寸 int targetW = imageView.getWidth(); int targetH = imageView.getHeight(); int inSampleSize = 1; if (options.outHeight > targetH || options.outWidth > targetW) { final int halfHeight = options.outHeight / 2; final int halfWidth = options.outWidth / 2; while ((halfHeight / inSampleSize) >= targetH && (halfWidth / inSampleSize) >= targetW) { inSampleSize *= 2; } } // 实际解码 options.inJustDecodeBounds = false; options.inSampleSize = inSampleSize; InputStream newInputStream = getContentResolver().openInputStream(uri); Bitmap bitmap = BitmapFactory.decodeStream(newInputStream, null, options); newInputStream.close(); imageView.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); } } // 观察者中调用该方法即可 - 补充检查项
确认对应dpi资源目录下pet_picture_width和pet_picture_height的dimen值配置正确,不存在异常极小的配置。
内容的提问来源于stack exchange,提问作者dacal
相关产品推荐
相关产品推荐

