在更改应用程序的夜间模式后,我已经看到了很多有关重新创建当前活动的问题和答案,但是对于如何刷新后退堆栈活动却一无所知。
说我有后栈 A> B> C 。活动C允许通过调用AppCompatDelegate.setDefaultNightMode()
更改夜间模式。调用之后,当前活动(C)可以使用delegate.applyDayNight()
或recreate()
刷新其主题。
但是,当用户导航回B或A时,无论白天还是晚上,活动仍在使用“旧”模式。
我试图在“活动”中添加类似内容:
override fun onResume() {
super.onResume()
delegate.applyDayNight()
}
但是它似乎不起作用。
我多次尝试解决此问题:
一个想法是完全像建议的here或here一样重新创建Backstack,但是由于backstack不是静态的,因此对我来说是不可行的。
另一个想法是拥有一个处理夜间模式更改并提供LiveData的类。每个活动都会监听LiveData进行模式更改,然后调用recreate()
。但是,我们陷入了无限循环,因为Activity将在开始收听LiveData之后直接重新创建。
我很难相信,我是第一个尝试在更改夜间模式后从后台刷新“活动”的人。我想念什么?
谢谢!
答案 0 :(得分:1)
快速解答:
@Override
protected void onRestart() {
super.onRestart();
recreate();
}
您将以上代码添加到MainActivity中,它将起作用。
答案 1 :(得分:0)
在项目中创建一个静态布尔变量,并在每个活动中检查布尔值是true还是false,然后根据值应用白天和黑夜。
答案 2 :(得分:0)
完全刷新您的后栈可能是过大的选择,可能会增加UX的开销/滞后。正如您提到的,大多数应用程序将无法访问完整的静态后备堆栈。
您实质上是在描述一个更一般的问题:对主题或WindowManager本身的全局更改会影响随后的视图绘制。但是堆栈中“活动”的先前布局可能不会重绘。在这种情况下,对于您来说似乎很奇怪,但是也有很多很好的理由,如果用户再次使用它,就不想在堆栈中重画一个Activity。因此,这不是自动功能。
我可以想到几个选择:
1)编写一个继承自Activity的自定义类,当它再次移到堆栈的最前面时,它将使所有视图无效。例如。在onResume()
或onRestart()
中,致电(如果在Fragment
中)
View view = getActivity().findViewById(R.id.viewid);
view.invalidate();
将此自定义活动用于要与当前日/夜模式保持一致的所有活动。
2)使用ActivityLifecycleCallbacks
。这有助于将所有逻辑保持在一个地方,并且避免了如上所述的自定义继承的需求。您可以根据需要在此处暂停/恢复活动,从而使视图无效。例如,如果更改主题的是您的应用,则可以包括一个侦听器,并记录为SharedPreference
。
要使用,请将回调添加到您的Application类:
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void
onActivityCreated(Activity activity, Bundle savedInstanceState) {
//can check type of Activity for custom behaviour, if using inheritance
if(activity instanceof MainActivity) {
mMainActivities.put(activity, new MainActivityEntry((MainActivity)activity));
//...
}
}
@Override
public void
onActivityDestroyed(Activity activity) {
}
@Override
public void
onActivityPaused(Activity activity) {
}
@Override
public void
onActivityResumed(Activity activity) {
if(activity instanceof MainActivity) {
//...
}
//can update Entry properties too
final MainActivityEntry activityEntry = mMainActivities.get(activity);
if(activityEntry != null) {
//record state /perform action
}
}
@Override
public void
onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void
onActivityStarted(Activity activity) {
}
@Override
public void
onActivityStopped(Activity activity) {
}
});