问题
I have a custom theme with Theme.AppCompat.DayNight.NoActionBar
as the parent with resources for both day and night modes.
In the documentation, there is a method provided to change the theme and unless the current activity is recreated, the theme will only change the next time that activity is launched.
Twitter and Pocket on the other hand change the themes without recreating the activity the user is on.
How can i achieve this?
回答1:
Twitter and Pocket on the other hand change the themes without recreating the activity the user is on.
How do you know? If you handle saved state correctly and provide an animation that doesn't look like changing windows you can make activity recreation look good enough. In fact you can make it look so good that you even wouldn't recognize the activity was recreated.
Running adb shell dumpsys activity
gives the following output before and after toggling night mode in Twitter:
ResumedActivity: ActivityRecord{40c4156 u0 com.twitter.android/com.twitter.app.main.MainActivity t11398}
ResumedActivity: ActivityRecord{adca640 u0 com.twitter.android/com.twitter.app.main.MainActivity t11399}
Notice the activity hash code changed - the activity did recreate. This is true for both a recent version of Twitter and for Twitter 6.22.1 published on Nov 9, 2016.
Changing theme is a non-trivial task. You'd have to traverse the whole view hierarchy and change all the background colors, text colors, ripples (good luck with this one), and you'd have to make sure that any future call to getResources().get*
will return the correct resources.
On the other hand you could just call Activity.recreate()
and let the system do what it's already programmed to do.
After that you could call Activity.overridePendingTransition(...)
with some animations that don't change window size and position. There are more ways to animate the window transition.
来源:https://stackoverflow.com/questions/40526569/changing-app-theme-without-recreating-activity