Recreate the backstack in Android
Asked Answered
W

1

12

I have just implemented a way to change the theme in my app. Pressing a button sets a value in SharedPreferences, then the Activity is recreated, and the theme is changed due to the flag.

The problem is how to handle the backstack. Simply recreating the activity is not good because pressing the hardware back button will resume the previous activity (with the old theme still set), whereas if the user did the following:

Start in Activity A > B > C > Press theme change button > Press hardware back button

Then I want them to be taken back to Activity B with the new theme correctly applied. The best solution I've found so far is to recreate the backstack based on the object hierarchy as follows:

    Intent intent = new Intent();
    intent.setClass(activity, activity.getClass());
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(activity);
    stackBuilder.addNextIntentWithParentStack(intent);
    stackBuilder.startActivities(new Bundle());

However the Activity hierarchy in our app is not well defined (i.e. C can have multiple parents), therefore the code above can lead to the user being taken back to an unexpected activity after pressing the back button.

Is there a clean way to rebuild the back-stack based on the actual back-stack rather than the Activity hierarchy?

Whirl answered 3/7, 2015 at 3:12 Comment(0)
B
0

One solution I'm using for now, which granted isn't perfect but avoids having to make any changes to the backstack, is to use the onResume() method.

In the onResume() for all activities, the themeKey is checked for changes. If different then the activity is recreated. My onCreate() sets the theme, so if recreated the new theme gets applied. Meaning that as the user moves through the backstack, if the theme has been changed it will update.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SharedPreferences sharedPreferences = getSharedPreferences("ThemePref", Context.MODE_PRIVATE);
    themeKey = sharedPreferences.getInt("themeKey",R.style.GM1);
    getTheme().applyStyle(themeKey,true);
    setContentView(R.layout.activity_settings);
}

@Override
protected void onResume() {
    super.onResume();
    SharedPreferences sharedPreferences = getSharedPreferences("ThemePref", Context.MODE_PRIVATE);
    int newThemeKey = sharedPreferences.getInt("themeKey",R.style.GM1);
    if (newThemeKey != themeKey){
        recreate();
    }
}

5 years too late, but hopefully it helps someone!

Beaujolais answered 11/10, 2020 at 17:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.