Android Studio选中图片无法在ImageView预览的问题求助
解决Firebase图片上传中ImageView预览不显示的问题
嘿,我仔细看了你的代码,上传功能没问题但预览不显示,主要是布局约束错误和图片加载方式可能存在内存问题这两个点导致的,咱们来一步步修复:
1. 修复ConstraintLayout的布局约束问题
你的布局用了ConstraintLayout,但里面的LinearLayout用了android:layout_alignParentTop="true"——这是RelativeLayout的属性,在ConstraintLayout里完全无效!而且ImageView也没有设置任何约束,这会导致它的位置和显示区域异常,甚至被上面的按钮栏挡住。
修改后的布局代码:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".UploadImage"> <LinearLayout android:id="@+id/layout_button" android:orientation="horizontal" android:weightSum="2" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"> <Button android:id="@+id/btnChoose" android:text="Choose" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:id="@+id/btnUpload" android:text="Upload" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> </LinearLayout> <ImageView android:id="@+id/imgView" android:layout_width="match_parent" android:layout_height="0dp" android:scaleType="centerCrop" app:layout_constraintTop_toBottomOf="@+id/layout_button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </android.support.constraint.ConstraintLayout>
这里做了几个关键修改:
- 给
LinearLayout加上了ConstraintLayout的顶部约束,确保它固定在屏幕顶部 - 给
ImageView设置了上下左右的约束,让它填充按钮栏下方的所有区域 - 给
ImageView添加了android:scaleType="centerCrop",保证图片显示比例正常
2. 优化图片加载逻辑,避免内存溢出
你当前用MediaStore.Images.Media.getBitmap()直接加载图片,如果选中的是大尺寸图片(比如手机相机拍的原图),很容易触发OOM(内存溢出),导致图片加载失败,自然就看不到预览了。
推荐两种解决方案:
方案一:用第三方图片加载库(推荐,简单高效)
比如用Glide,它会自动处理图片压缩、内存缓存和线程加载。
首先在你的build.gradle(Module级别)里添加依赖:
implementation 'com.github.bumptech.glide:glide:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
然后修改onActivityResult里的代码:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null ) { filePath = data.getData(); // 用Glide加载图片到ImageView Glide.with(this) .load(filePath) .centerCrop() .into(imageView); } }
方案二:手动压缩Bitmap(不依赖第三方库)
如果不想用第三方库,可以用BitmapFactory来采样缩小图片:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null ) { filePath = data.getData(); try { // 获取图片的宽高,不加载到内存 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; InputStream inputStream = getContentResolver().openInputStream(filePath); BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); // 计算采样率,把图片缩小到ImageView的尺寸(这里取屏幕宽度的一半为例) int reqWidth = getResources().getDisplayMetrics().widthPixels / 2; int reqHeight = getResources().getDisplayMetrics().heightPixels / 2; options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 加载压缩后的Bitmap options.inJustDecodeBounds = false; inputStream = getContentResolver().openInputStream(filePath); Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); imageView.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "图片加载失败", Toast.LENGTH_SHORT).show(); } } } // 计算采样率的工具方法 private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
3. 额外检查:权限问题
如果你的设备是Android 6.0(API 23)及以上,别忘了申请读取外部存储的动态权限,否则可能无法读取选中的图片。可以在chooseImage()方法里先检查权限:
private void chooseImage() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100); return; } Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST); } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { chooseImage(); } else { Toast.makeText(this, "需要存储权限才能选择图片", Toast.LENGTH_SHORT).show(); } }
把这些修改做完后,再测试一下,选中图片后应该就能正常在ImageView里看到预览啦!
内容的提问来源于stack exchange,提问作者user7407296
相关产品推荐
相关产品推荐

