Search code examples
javaandroidandroid-bundle

Setting EditText in Bundle test not working


Hi I am practicing how Bundle savedInstanceState works in Activity creation and it restoration. I have tried this:

private EditText mTextBox;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextBox = (EditText) findViewById(R.id.etName);
        mTextBox.setText("hello");
        if(savedInstanceState != null){
            Toast.makeText(this, savedInstanceState.getString("name"), 
                       Toast.LENGTH_SHORT).show();
        mTextBox.setText(savedInstanceState.geteString("name"));
    }
}

  @Override
  protected void onSaveInstanceState(Bundle outState) {
      outState.putString("name", "Joe");
      super.onSaveInstanceState(outState);
}

On first onCreate() obviously this will set the EditText field with "hello" as savedInstanceState is null the if block will not be executed. When I change the orientation the Activity goes through all callbacks and Toast the String in the if block, however, it does not set the mTextBox with value from Bundle passed in. The EditText is still set to hello instead of Joe, however, the Toast in if block shows Joe.

Can anyone point out why this is not working as my expectation?

Thanks


Solution

  • This is happening as a result of TextView.getFreezesText, which will:

    Return whether this text view is including its entire text contents in frozen icicles. For EditText it always returns true.

    And some more info from TextView.setFreezesText:

    Control whether this text view saves its entire text contents when freezing to an icicle, in addition to dynamic state such as cursor position. By default this is false, not saving the text. Set to true if the text in the text view is not being saved somewhere else in persistent storage (such as in a content provider) so that if the view is later thawed the user will not lose their data. For EditText it is always enabled, regardless of the value of the attribute.

    icicles is referring to savedInstanceState, that's just what it used to be called.

    If you'd like to save and restore the text yourself, you could create a custom EditText and override getFreezesText, something like:

    public class NonFreezingEditText extends AppCompatEditText {
    
        public NonFreezingEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean getFreezesText() {
            return false;
        }
    
    }
    

    You could also use View.post:

    mTextBox.post(() -> mTextBox.setText(savedInstanceState.getString("name")));
    

    or Activity.onRestoreInstanceState

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mTextBox.setText(savedInstanceState.getString("name"));
    }