Android 更改布局时保存位图

Android 更改布局时保存位图,android,bitmap,Android,Bitmap,我有一个纵向布局和一个横向布局。在这些布局中,有一个带有onClick侦听器的ImageView。My ImageView有一个默认图像和一个相机图标 当我进入ImageView时,打开一个对话框,我可以打开相机并拍照,或者打开gallery并选择图像。 然后,我保存一个位图并将其放在ImageView中。这个位图在我的类中是一个全局变量 但当我打开我的应用程序,加载我的其他布局主视图时,如果我拍了一张照片,我会丢失位图并对默认图像收费 这是我的代码: public void takePictu

我有一个纵向布局和一个横向布局。在这些布局中,有一个带有onClick侦听器的ImageView。My ImageView有一个默认图像和一个相机图标 当我进入ImageView时,打开一个对话框,我可以打开相机并拍照,或者打开gallery并选择图像。 然后,我保存一个位图并将其放在ImageView中。这个位图在我的类中是一个全局变量

但当我打开我的应用程序,加载我的其他布局主视图时,如果我拍了一张照片,我会丢失位图并对默认图像收费

这是我的代码:

public void takePicture(View view) {

    final CharSequence[] options = { "Take a pic", "Gallery","Cancel" };


    //Build an AlertDialog object
    AlertDialog.Builder builder = new AlertDialog.Builder(Main.this);
    builder.setTitle("Picture");

    //onClickListener method
    builder.setItems(options, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int selected) {
            if(options[selected].equals("Take a pic")){
                //open camera
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
                //this is my global bitmap and I put it null when I push take a picture
                resized=null;
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                startActivityForResult(intent, 1);
            }
            else if(options[selected].equals("Gallery")){
                Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 2);
            }
            else{
                dialog.dismiss();
            }
            //if user doesn't select anything, show default icon
            //show picture is my layout ImageView and cameraicon is my default icon
            showPicture.setImageResource(R.drawable.cameraicon);
        }
    });
    builder.show();
}
这是我的onActivityResult代码:

protected void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode, resultCode, data);


    //if my resultCode is RESULT_OK
    if(resultCode == RESULT_OK){
        if(requestCode==1){
            File f = new File(Environment.getExternalStorageDirectory().toString());
            for(File temp: f.listFiles()){
                if(temp.getName().equals("temp.jpg")){
                    f=temp;
                    break;
                }
            }
            try{
                Bitmap bitmap;
                BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
                bitmap = BitmapFactory.decodeFile(f.getAbsolutePath());

                newHeight=600;
                newWidth=900;
                //resized is my global bitmap
                resized = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);

                //show my new bitmap in my ImageView
                showPicture.setImageBitmap(resized);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //I choose gallery option
        else if(requestCode==2){
            Uri selectedImage = data.getData();
            String[] filePath = {MediaStore.Images.Media.DATA};
            Cursor c = getContentResolver().query(selectedImage,filePath,null,null,null);
            c.moveToFirst();
            int columnIndex = c.getColumnIndex(filePath[0]);
            String picturePath = c.getString(columnIndex);
            c.close();
            Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));

            newHeight=600;
            newWidth=900;
            //my global bitmap
            resized = Bitmap.createScaledBitmap(thumbnail, newHeight, newWidth, true);
            //show new bitmap in my ImageView
            showPicture.setImageBitmap(resized);
        }
    }
}
当我打开手机时,我松开了位图。请问我能做什么?
非常感谢

我认为您可以通过调用OnSaveInstanceStateBundle来保存位图的值,然后在重新创建活动时将其还原。

您可能希望将文件名存储到活动中的照片文件中:

class MyActivity {
    File imageFile = null;
}
由于您的活动将在旋转时被销毁,因此需要将该图像文件名保存在onSaveInstanceState中:

android中的位图是可打包的,因此您可以保存位图本身,而不是存储图像的文件名

重新创建活动时,保存的状态将传递给onCreate:

public void onCreate(Bundle savedState)
{
    super.onCreate(savedState);
    if (savedState != null) {
         String imagePath = saveState.getString("IMAGE_FILENAME");
         if (imagePath != null) {
             imageFile = new File(imagePath);
         }
    }
    updateImageView();
} 

public void updateImageView()
{
    // code from onActivityResult() to load the image
}
旁注:

File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp: f.listFiles()) {
    if (temp.getName().equals("temp.jpg")) {
        f = temp;
        break;
    }
}
您正在写入全局外部存储目录。请不要这样做,请使用应用程序的文件目录。此外,无需在路径中搜索固定的文件名,只需检查文件是否存在

File imageFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), imageFileName);
if (imageFile.exists()) {
   [...]
}

我认为更好的方法是使用片段而不是活动。
使用方法fragment.setRetainInstancetrue,当您打开设备时,片段不会被销毁

您没有显示onCreate方法,这在这里有点重要,因为android默认情况下会销毁并重新创建配置更改(如旋转)中最重要的活动。该活动也可能会因为其他原因被销毁并重新创建。因此,保存实例状态或多或少是强制性的,尽管如此。setRetainInstancetrue允许您的片段仅在配置更改期间存在,例如,切换到另一个应用程序可能会导致图像静止消失。好的,这是一个重要的修改。谢谢
File imageFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), imageFileName);
if (imageFile.exists()) {
   [...]
}