Android在Dialog中拍照并显示到ImageView与RecyclerView的问题问询
问题根源
你现在的错误主要来自3个地方:
- 查找Dialog内ImageView的方法错误:
imageView = (ImageView) findViewById(R.id.image_view);是从Activity的布局中查找控件,自然找不到Dialog内的目标控件,必须用dialog.findViewById - 相机调用时Activity可能触发重建,Dialog会被销毁,直接持有Dialog内控件的引用必然会出现空指针
- 数据层和列表适配器没有适配图片字段,提交后无法同步到RecyclerView
具体修改方案
1. 新增全局变量
在MainActivity的类属性里新增以下变量:
// 临时存储拍摄的照片 private Bitmap tempCaptureBitmap; // 持有当前打开的Dialog引用,注意 onDestroy 要置空避免内存泄漏 private Dialog addNoteDialog;
2. 调整showDialog方法逻辑
修改后的showDialog代码如下:
public void showDialog() { final EditText title, des; Button submit; Button takepicture; ImageView imageView; addNoteDialog = new Dialog(this); addNoteDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); WindowManager.LayoutParams params = new WindowManager.LayoutParams(); addNoteDialog.setContentView(R.layout.dialog); View v = getWindow().getDecorView(); v.setBackgroundResource(android.R.color.transparent); params.copyFrom(addNoteDialog.getWindow().getAttributes()); params.height = WindowManager.LayoutParams.MATCH_PARENT; params.width = WindowManager.LayoutParams.MATCH_PARENT; params.gravity = Gravity.CENTER; addNoteDialog.getWindow().setAttributes(params); addNoteDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); addNoteDialog.show(); title = (EditText) addNoteDialog.findViewById(R.id.title); des = (EditText) addNoteDialog.findViewById(R.id.description); submit = (Button) addNoteDialog.findViewById(R.id.submit); takepicture = (Button) addNoteDialog.findViewById(R.id.takepicture); // 修复:从Dialog布局查找ImageView imageView = (ImageView) addNoteDialog.findViewById(R.id.image_view); // 如果已经有拍摄的临时图片,直接预览 if (tempCaptureBitmap != null) { imageView.setImageBitmap(tempCaptureBitmap); } // 权限和拍照用不同请求码避免冲突 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 200); } submit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (title.getText().toString().isEmpty()) { title.setError("Please Enter Title"); } else if (des.getText().toString().isEmpty()) { des.setError("Please Enter Description"); } else { // 这里要修改DatabaseHelper的addNotes方法,新增图片参数 // 建议把tempCaptureBitmap存到应用沙盒目录,把路径传到数据库 database_helper.addNotes(title.getText().toString(), des.getText().toString(), getImageSavePath(tempCaptureBitmap)); addNoteDialog.cancel(); // 清空临时图片 tempCaptureBitmap = null; displayNotes(); } } }); takepicture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, 100); } }); // Dialog销毁时清空引用 addNoteDialog.setOnDismissListener(dialogInterface -> { addNoteDialog = null; }); } // 新增工具方法:把Bitmap存到本地返回路径,可根据自己需求实现 private String getImageSavePath(Bitmap bitmap) { // 此处省略存储逻辑,直接返回路径即可 return ""; }
3. 修改onActivityResult逻辑
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 100 && resultCode == RESULT_OK && data != null) { tempCaptureBitmap = (Bitmap) data.getExtras().get("data"); // 判断Dialog是否还在显示,显示的话更新预览 if (addNoteDialog != null && addNoteDialog.isShowing()) { ImageView iv = addNoteDialog.findViewById(R.id.image_view); if (iv != null) { iv.setImageBitmap(tempCaptureBitmap); } } } }
4. 其他配套修改
- 给
NoteModel新增图片路径字段,新增对应的get/set方法 - 给
DatabaseHelper的表结构新增图片路径的列,修改addNotes和getNotes方法适配该字段 - 给
NotesAdapter的条目布局新增ImageView,在绑定数据的时候根据图片路径加载图片到控件
内容的提问来源于stack exchange,提问作者user3788604
相关产品推荐
相关产品推荐

