2

My activity has an ImageView. It gets an image from take picture action. This activity has two layouts. Two layouts

In the manifest, there is:

The manifest

My problem is, that if I remove

configChanges="orientation|keyboardHidden|screenSize"

data won't save but if not, form_layout.xml (land) won't load. What loads on screenRotate is a default landscape layout.

How can I solve my problem which is to load new xml layout after rotation with saved data?

UPDATE

I don't want to keep

configChanges="orientation|keyboardHidden|screenSize"
xenteros
  • 15,586
  • 12
  • 56
  • 91

3 Answers3

2

If you want to keep configChanges="orientation|keyboardHidden|screenSize" you need to manually call setContentView again

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    //Get last state
    String text = et1.getText().toString();

    //Create new view according to layout
    setContentView(R.layout.activity_login);

    // Restore last state
    et1 = (EditText) findViewById(R.id.et1);
    et1.setText(text);
}

Otherwise your best bet is to save data to Bundle onSaveInstanceState and restore it in the onCreate

See here http://developer.android.com/training/basics/activity-lifecycle/recreating.html

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        // Save the user's current game state
        savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
        savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

        // Always call the superclass so it can save the view hierarchy state
        super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // Always call the superclass first

        // Check whether we're recreating a previously destroyed instance
        if (savedInstanceState != null) {
            // Restore value of members from saved state
            mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
            mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
        } else {
            // Probably initialize members with default values for a new instance
        }
        ...
    }
Bojan Kseneman
  • 15,488
  • 2
  • 54
  • 59
1

Problem solved!

Let me explain. When you add

android:configChanges="orientation|keyboardHidden|screenSize"

you declare, that any changes will be done manually, so it's better to resign from this solution for another one, I'll describe below.

My problem Was keeping more complicated - then text - content from one layout to another. The key is, that orientation or screen size change causes activity destroy. After the destroy activity is created again, so method onCreate is called and the activity life cycle runs again.

It is a good practice, to put every data into a bundle if it's not restoreable from the database.

Let mi show you my code:

    @Override
    public void onSaveInstanceState(Bundle outState){
        Log.d("debug", "onSaveInstanceState");
        super.onSaveInstanceState(outState);
        if(pictureAdded){
            outState.putBoolean(ADDED, true);
            outState.putString(PATH, currentPhotoPath);
        }else{
            outState.putBoolean(ADDED, false);
        }
    }

pictureAdded is my flag which is true if the user has already taken a picture, so the picture is stored in the memory, and it's file path exists.

This method is called before destroy. On create, we want to check if it is activity's first onCreate or not or at least if there was picture taken before.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.form_layout);
    pictureAdded = false;
    if (savedInstanceState == null){
        return;
    }
    if (savedInstanceState.containsKey(ADDED)){
        if (savedInstanceState.getBoolean(ADDED)){
            try{
                currentPhotoPath = savedInstanceState.getString(PATH);
                photoPreview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        photoPreview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        setPic();
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

The first part of the onCreate() method is as usually. Then you have to check if bundle exists. Then it's a good practice to use the data stored at the key if and only if the key exists.

When we wish to add a picture to an ImageView, the thing is getting harder. Why? Because at this point, imageView's dimensions are 0px x 0px. How to solve it? The solution is posted above. Use treeobserver pattern. This part of code provides you, that the code in

@Override
public void onGlobalLayout(){
    //here
}

will be called right after layout is created, so it's parts have dimensions. If you wish to do the code once, remove onGlobalLayoutListener.

Hope, to help someone.

xenteros
  • 15,586
  • 12
  • 56
  • 91
0

check this,it may help
Save data and change orientation

Community
  • 1
  • 1
Srishti Roy
  • 576
  • 5
  • 17
  • Thanks, but it doesn't. I got an answer from a friend of mine, to remove configChanges from manifest and put the data to the Bundle in onSaveInstanceState. I'll respond if it works. – xenteros May 22 '15 at 11:05