0

I'm trying to understand the Instance state concept in Android. The documentation available at https://developer.android.com/guide/components/activities/activity-lifecycle describes that

The saved data that the system uses to restore the previous state is called the instance state and is a collection of key-value pairs stored in a Bundle object. By default, the system uses the Bundle instance state to save information about each View object in your activity layout (such as the text value entered into an EditText widget). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more state information that you'd like to restore, such as member variables that track the user's progress in the activity.

Note: In order for the Android system to restore the state of the views in your activity, each view must have a unique ID, supplied by the android:id attribute.

I made an example with all the requisites described above, nevertheless it still doesn't work as I expected: after clicking the button, and changing the background color of LinearLayout, which have an unique Id, it looses color after rotating screen. The radio button remains selected as expected though.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.widget.LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="?android:dividerHorizontal"
    android:orientation="vertical"
    android:padding="16dp"
    android:showDividers="middle">


    <android.widget.LinearLayout
        android:id="@+id/layout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:text="Question 1?" />


        <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <RadioButton
                android:id="@+id/radio_p1o1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="option1" />

            <RadioButton
                android:id="@+id/radio_p1o2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="option2" />

            <RadioButton
                android:id="@+id/radio_p1o3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="option3" />
        </RadioGroup>
    </android.widget.LinearLayout>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="16dp"
        android:onClick="changeColor"
        android:text="Change Background Color" />
</android.widget.LinearLayout>
</ScrollView>

and MainActivity.java

package com.example.android.testlinearlayoutpropertiessave;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import static android.graphics.Color.GREEN;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    public void changeColor(View view) {
        findViewById(R.id.layout1).setBackgroundColor(GREEN);
    }
}

Am I doing something wrong, misunderstood the functionality or is there any reason that make it not saving also the backgroundColor of LinearLayout?

Thanks

P.S.: I already get it working, coding, I just want to know which properties are covered automatically!

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
pablo.vix
  • 2,103
  • 2
  • 15
  • 12
  • Possible duplicate of [Activity restart on rotation Android](https://stackoverflow.com/questions/456211/activity-restart-on-rotation-android) – gmetax May 31 '18 at 13:45
  • check about screen rotation and saveInstanceState – gmetax May 31 '18 at 13:45
  • That description is misleading. Not everything is handled automatically. Only certain properties are automatically saved and restored for particular `View`s. `EditText`'s text is one of those. Others include the checked state of a `CheckBox`, the scroll position of a `ListView`, etc. Basically, the main functional properties of a given `View` type. The background color of a `LinearLayout` is not one that is saved and restored automatically. You'd need to handle that yourself, like is described after that quoted section on the linked page. – Mike M. May 31 '18 at 13:46

2 Answers2

0

You must retrieve the savedInstanceState to do anything with it.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Restore from saved state
    } else {
        // New instance
    }
    setContentView(R.layout.activity_main);

}

This should answer any remaining questions

It is entirely up to you what you save in your savedInstanceState bundle.

You simply use savedInstanceState.putInt("savedNum", 300); in an onSavedInstanceState call, then once returning to your view - in onCreate, check that savedInstanceState is not null and retrieve the value using int oldNum = savedInstanceState.getInt("savedNum");

Jantzilla
  • 638
  • 1
  • 7
  • 19
  • All right, I've made it work overriding the saveOnInstance method, but I just want to know what properties are saved by default and what are not! Just by reading the reference it is not clear! – pablo.vix Jun 03 '18 at 22:02
0

You must define a flag to indicate the state change, update the value of the flag in the changeColor method, and implement the method onSaveInstanceState. Example:

package com.example.android.testlinearlayoutpropertiessave;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import static android.graphics.Color.GREEN;

public class MainActivity extends AppCompatActivity {

    private boolean colorChanged = false;

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

        if (savedInstanceState != null) {
            colorChanged = savedInstance.getBoolean("colorChanged");
        }

        if (colorChanged) {
            findViewById(R.id.layout1).setBackgroundColor(GREEN);
        }
    }

    public void changeColor(View view) {
        findViewById(R.id.layout1).setBackgroundColor(GREEN);
        colorChanged = true;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(colorChanged);
    }
}
bra_racing
  • 622
  • 1
  • 8
  • 32
  • All right, I've made it work, but I just want to know what properties are saved by default and what are not! Just by reading the reference it is not clear! – pablo.vix Jun 03 '18 at 22:01
  • No properties are saved if you don't saved it in the ``onSaveInstanceState`` method. In an activity state change, the activity restarts its state (and the state of the variables and visual components) to the default one. – bra_racing Jun 04 '18 at 06:26