I have written android app now for a long time but now I'm facing a problem that I have never thought about. It is about the android lifecycle of Activitys
and Fragments
in in relation to configuration changes. For this I have create a small application with this necessary code:
public class MainActivity extends FragmentActivity {
private final String TAG = "TestFragment";
private TestFragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
fragment = (TestFragment) fm.findFragmentByTag(TAG);
if (fragment == null) {
fragment = new TestFragment();
fm.beginTransaction().add(R.id.fragment_container, fragment, TAG).commit();
}
}
}
And here is my code for the TestFragment
. Note that I'm calling setRetainInstance(true);
in the onCreate
method so the fragment is not recrated after a configuration change.
public class TestFragment extends Fragment implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater li, ViewGroup parent, Bundle bundle) {
View rootView = li.inflate(R.layout.fragment_test, parent, false);
Button button = (Button) rootView.findViewById(R.id.toggleButton);
button.setOnClickListener(this);
return rootView;
}
@Override
public void onClick(View v) {
Button button = (Button) v;
String enable = getString(R.string.enable);
if(button.getText().toString().equals(enable)) {
button.setText(getString(R.string.disable));
} else {
button.setText(enable);
}
}
}
And here is the layout that my fragment is using:
<LinearLayout
...>
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/toggleButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/enable"/>
</LinearLayout>
My problem is that if I rotate the device the text of the Button
change back to the default value. Of course the View
of the Fragment
is new created and inflated but the saved instance for the Views should be restored. I also have an EditText
in my layout and there the text and other properties remains after the rotation. So why is the Button not restore from the Bundle
by default? I have read on the developer site:
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 object). 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.
I've also read a lot of answers the last days but I do not know how actual they are anymore. Please do not leave a comment or an answer with android:configChanges=...
this is very bad practice. I hope someone can bring light into my lack of understanding.
In Android applications, each time a user rotates the screen, keyboard availability, etc., it is known as a configuration change. Configuration changes occur at runtime based on user actions. When such changes occur, Android components like Activities get recreated or restart.
setRetainInstance(true); // Start up the worker thread. mThread.start(); } /** * This is called when the Fragment's Activity is ready to go, after * its content view has been installed; it is called both after * the initial fragment creation and after the fragment is re-attached * to a new activity.
Activity is an application component that gives a user interface where the user can interact. The fragment is only part of an activity, it basically contributes its UI to that activity. Fragment is dependent on activity. It can't exist independently.
You should save state of your fragment in the onSaveInstanceState(Bundle outState)
and restore it in the onViewCreated(View view, Bundle savedState)
method. This way you will end up with the UI just as it was before configuration change.
TextView
subclasses don't save their text by default. You need to enable freezesText="true"
in the layout, or setFreezesText(true)
at runtime for it to save its state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With