首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AppCompatDelegate.setDefaultNightMode()仅仅是第一次被主要活动捕获?

AppCompatDelegate.setDefaultNightMode()仅仅是第一次被主要活动捕获?
EN

Stack Overflow用户
提问于 2018-11-17 23:48:37
回答 2查看 11.4K关注 0票数 8

运行Android P,使用androidx 1.0.0 (minSdkVersion 17)。从我的MainActivity,我打开了我的PreferenceActivity。在这里,我将更改UI主题,并重新创建活动以获取更改:

代码语言:javascript
复制
AppCompatDelegate.setDefaultNightMode(nightMode);
recreate();

更新主题后,我返回到MainActivity。在那里,主题被成功地更新。然后我重新打开PreferenceActivity并再次更改主题。

到目前为止还不错!

最后,我再次回到MainActivity。主题是未更新,如果您重复这些步骤,它将不会更新!

因此,复制的步骤似乎是:

  1. 来自活动A,开放活动B。
  2. 在B中,调用AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES),然后调用recreate()。主题更新了!
  3. 返回到A.主题更新了!
  4. 再次打开活动B。
  5. 在B中,调用AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO),然后调用recreate()。主题更新了!
  6. 返回到A主题是没有更新,如果重复步骤3-6,不是更新!

在从recreate()重试时,我尝试调用PreferenceActivity,但当库对主题更改作出反应时,会产生另一个问题:

代码语言:javascript
复制
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (...) {
        recreate();
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

当库对更新的主题没有反应时,它就会工作。否则,该活动将被重新创建两次(可能在调试时会更多),这会扼杀性能等等:

代码语言:javascript
复制
D/MainActivity: onActivityResult(): instance 1
D/MainActivity: onResume(): instance 1
D/MainActivity: onPause(): instance 1
D/MainActivity: onDestroy(): instance 1

D/MainActivity: onCreate(): instance 2
D/MainActivity: onResume(): instance 2
D/MainActivity: onPause(): instance 2
D/MainActivity: onDestroy(): instance 2

D/MainActivity: onCreate(): instance 3
D/MainActivity: onResume(): instance 3

Q:setDefaultNightMode() API是怎么回事?更重要的是,我如何成功地更新所有正在运行的活动,而不需要多次重新创建它们呢?

更新

这里有一个示例项目演示了这个问题:https://issuetracker.google.com/issues/119757688

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-03 19:33:00

我找到了一个很简单的解决这个问题的方法。在这两种情况下,它都能工作;当AppCompatActivity成功地重新创建自己时,以及当它不能成功地重新创建自己时。回想一下,activity A调用活动B,其中主题被更改,然后我们返回到主题并不总是被更新的A

活动B

在活动B (即偏好)中,我们跟踪主题的变化:

代码语言:javascript
复制
private boolean mThemeChanged;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mThemeChanged = getIntent().getBooleanExtra(EXTRA_THEME_CHANGED, false);
}

private void onNightModeChanged() {
    int nightMode = getNightModeFromPreferences();
    if (AppCompatDelegate.getDefaultNightMode() != nightMode) {
        AppCompatDelegate.setDefaultNightMode(nightMode);

        getIntent().putExtra(EXTRA_THEME_CHANGED, true);
        getDelegate().applyDayNight();
    }
}

我们将这段信息提供给呼叫活动,即Main:

代码语言:javascript
复制
@Override
public void finish() {
    Intent data = new Intent();
    data.putExtra(EXTRA_THEME_CHANGED, mThemeChanged);
    setResult(RESULT_OK, data);

    super.finish();
}

活动A

然后,在活动A中,我们使用以下信息:

代码语言:javascript
复制
private boolean mShouldRecreateActivity;

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ActivityResults.OPEN_SETTINGS_RESULT) {
        if (data != null && data.getBooleanExtra(SetPreferenceActivity.EXTRA_THEME_CHANGED, false)) {
            mShouldRecreateActivity = true;
        }
    }
}

@Override
protected void onResume() {
    super.onResume();

    if (mShouldRecreateActivity) {
        recreate();
        return; // No need to continue resuming!
    }
}

@Override
public void recreate() {
    super.recreate();

    mShouldRecreateActivity = false;
}

在罕见的情况下(通常是第一次),AppCompatActivity将正确地调用recreate() --我们的标志将被重置,避免了到达onResume()时额外的活动再活动。因此,这个代码应该是未来证明的。不过,我真的希望在下一个版本的androidx中解决这个问题,这样我们就可以解决这个问题了。

更新

看起来这是用AppCompat 1.1.0修复的。我不再需要这个解决办法来获得所期望的行为。

票数 2
EN

Stack Overflow用户

发布于 2018-11-18 00:45:58

更改夜间模式时,将模式值存储为共享首选项。

代码语言:javascript
复制
AppCompatDelegate.setDefaultNightMode(nightMode);
recreate(); //only recreate setting activity 
...//store mode value, these lines are omitted,please complete yourself

在其他活动onCreate()方法中:

代码语言:javascript
复制
...//get mode from share preference, these lines are omitted.
AppCompatDelegate.setDefaultNightMode(mode)//must place before super.onCreate();
super.onCreate(savedInstanceState);
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53356664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档