Android Fragment中实现Button拍照后图片显示至ImageView的方法
解决Fragment中拍照后将照片显示在ImageView的问题
嘿,我来帮你搞定这个问题!你已经能成功唤起相机了,接下来只需要处理拍照后的返回结果,把照片加载到ImageView里就行。我给你分几种场景来讲解,从简单到进阶:
一、快速实现:显示相机返回的缩略图(简单版)
如果你只是需要快速显示一张小尺寸的照片,可以直接用相机返回的缩略图:
- 首先给相机请求定义一个请求码常量,在Fragment里添加:
private static final int REQUEST_IMAGE_CAPTURE = 1;
- 修改按钮点击事件里的相机启动代码,用
startActivityForResult替代startActivity:
capture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 先检查是否有可用的相机应用,避免崩溃 if (intent.resolveActivity(requireActivity().getPackageManager()) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); } } });
- 在Fragment里重写
onActivityResult方法,处理返回的照片:
@Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); // 匹配请求码且拍照成功 if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) { // 从Intent中获取缩略图Bitmap Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); // 找到你的ImageView并设置图片 ImageView imageView = getView().findViewById(R.id.your_imageview_id); // 替换成你布局里ImageView的ID imageView.setImageBitmap(imageBitmap); } }
二、推荐方案:使用Activity Result API(替代已废弃的startActivityForResult)
注意startActivityForResult已经被官方废弃了,现在更推荐使用Activity Result API,用法如下:
- 在Fragment里定义一个
ActivityResultLauncher成员变量:
private ActivityResultLauncher<Intent> takePictureLauncher;
- 在
onCreateView方法里初始化这个Launcher,设置结果回调:
takePictureLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { Intent data = result.getData(); if (data != null) { Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); ImageView imageView = getView().findViewById(R.id.your_imageview_id); imageView.setImageBitmap(imageBitmap); } } });
- 修改按钮点击事件的启动代码:
capture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(requireActivity().getPackageManager()) != null) { takePictureLauncher.launch(takePictureIntent); } else { Toast.makeText(requireContext(), "未找到可用的相机应用", Toast.LENGTH_SHORT).show(); } } });
三、进阶:获取高清全尺寸照片
上面两种方式拿到的都是缩略图,如果需要高清的全尺寸照片,需要指定照片的保存路径,具体步骤:
步骤1:创建保存照片的方法
在Fragment里添加创建临时照片文件的方法:
private File createImageFile() throws IOException { // 生成唯一的文件名,避免重复 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; // 获取应用专属的图片存储目录 File storageDir = requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempFile(imageFileName, ".jpg", storageDir); }
步骤2:配置FileProvider
因为Android 7.0之后不能直接传递文件URI,需要用FileProvider来共享文件:
- 在
AndroidManifest.xml的<application>标签内添加FileProvider配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.your.package.name.fileprovider" <!-- 替换成你的包名+fileprovider --> android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
- 在
res/xml目录下创建file_paths.xml文件(如果没有xml目录就新建一个):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 指定共享应用外部存储的Pictures目录 --> <external-files-path name="my_images" path="Pictures" /> </paths>
步骤3:修改拍照逻辑和回调
更新Fragment的代码,添加文件引用并修改逻辑:
public class NewVisitorFragment extends Fragment { private Button capture; private File photoFile; // 保存拍照后的文件引用 private ActivityResultLauncher<Intent> takePictureLauncher; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootview = inflater.inflate(R.layout.fragment_new_visitor, container, false); capture = rootview.findViewById(R.id.capture); // 初始化拍照结果回调 takePictureLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { // 拍照成功后,从文件加载全尺寸图片 if (photoFile != null && photoFile.exists()) { Bitmap fullSizeBitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath()); ImageView imageView = rootview.findViewById(R.id.your_imageview_id); // 替换成你的ImageView ID imageView.setImageBitmap(fullSizeBitmap); } } }); capture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(requireActivity().getPackageManager()) != null) { try { photoFile = createImageFile(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(requireContext(), "创建照片文件失败", Toast.LENGTH_SHORT).show(); return; } if (photoFile != null) { Uri photoURI = FileProvider.getUriForFile(requireContext(), "com.your.package.name.fileprovider", // 替换成你的包名+fileprovider photoFile); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); takePictureLauncher.launch(takePictureIntent); } } else { Toast.makeText(requireContext(), "未找到可用的相机应用", Toast.LENGTH_SHORT).show(); } } }); return rootview; } private File createImageFile() throws IOException { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempFile(imageFileName, ".jpg", storageDir); } }
这样就能实现点击按钮拍照,然后把高清照片显示在ImageView里啦!
内容的提问来源于stack exchange,提问作者Aditya Dabas
相关产品推荐
相关产品推荐

