关于android:ImageView在发生屏幕旋转时不保留Image

ImageView not retaining Image when Screen rotation occurs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    ImageView iv;
    Bitmap bTemp;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);




        Button cameraClick = (Button) findViewById(R.id.click);
        iv = (ImageView) findViewById(R.id.imageView1);

        final Bitmap data = (Bitmap) getLastNonConfigurationInstance();
        if (data == null) {

           iv.setImageBitmap(bTemp);
        }


        cameraClick.setOnClickListener(myhandler);

    }


    OnClickListener myhandler = new OnClickListener() {
        public void onClick(View v) {
            Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intent, 0);
        }
      };


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Bitmap bm = (Bitmap) data.getExtras().get("data");
        iv.setImageBitmap(bm);

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }




    @Override
    @Deprecated
    public Object onRetainNonConfigurationInstance() {
        bTemp = iv.getDrawingCache();
        return bTemp;
    }


}

我正在使用 imageview 来存储使用 Camera Intent 捕获的图像,但是当屏幕旋转时,图像会丢失。
我尝试使用 onRetainNonConfigurationInstance() 但它不起作用

我不想将图像写入文件。


您可以通过在清单文件中设置方向和屏幕大小标志来避免重新创建活动

1
android:configChanges="keyboard|orientation|screenSize"

如果需要,你可以实现 onConfigurationChanged() ,当方向改变时会调用它。更多信息在 http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange


这可能对你有帮助...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
protected void onSaveInstanceState(Bundle outState) {
    BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
    Bitmap bitmap = drawable.getBitmap();
    outState.putParcelable("image", bitmap);
    super.onSaveInstanceState(outState);
}

protected void onCreate(Bundle savedInstanceState) {
     if(savedInstanceState != null) {
        Bitmap bitmap = savedInstanceState.getParcelable("image");
        imageView.setImageBitmap(bitmap);
     }
}

屏幕旋转时图像消失的原因是活动被破坏并重新创建。
在此过程中,不会保留所选图像,您可以在此处阅读

Caution: Your activity will be destroyed and recreated each time the user rotates the screen. When the screen changes orientation, the system destroys and recreates the foreground activity because the screen configuration has changed and your activity might need to load alternative resources (such as the layout).

如果您想保留所选图像,则不应使用实例状态,您可以在此处阅读。

Bundle that the system saves for you with the onSaveInstanceState() callbacka€"it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a Fragment when your activity is restarted due to a configuration change. This fragment can contain references to stateful objects that you want to retain.

我实现了这个解决方案,您可以在我对其他问题的回答中找到代码


不要返回您甚至没有构建的 DrawingCache(顺便说一句),而是返回 Bitmap

实施:

在您的 onActivityResult 中,将位图保存在 bTemp:

1
2
3
4
5
6
7
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    bTemp = (Bitmap) data.getExtras().get("data");
    iv.setImageBitmap(bTemp);

}

在你的配置保存中,保存这个位图:

1
2
3
4
5
@Override
@Deprecated
public Object onRetainNonConfigurationInstance() {
    return bTemp;
}

getLastNonConfigurationInstance() 返回一个活动实例。您可以从该实例中获取先前的值:

在你的 onCreate():

1
2
3
4
5
YourActivity prevActivity = (YourActivity) getLastNonConfigurationInstance();

if(prevActivity!= null) {
      this.bTemp = prevActivity.bTemp;
   }

你的 onRetainNonConfigurationInstance() 方法应该是:

1
2
3
4
5
@Override
@Deprecated
public Object onRetainNonConfigurationInstance() {
    return bTemp;
}

你的 \\'onActivityResult()` 方法应该是:

1
2
3
4
5
6
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    bTemp = (Bitmap) data.getExtras().get("data");
    iv.setImageBitmap(bTemp);
}