如何更新 activity 使用后从首选项更改外观?

How to update activity after uses changes appearance from preferences?

当用户在我的应用程序上打开首选项时,他可能会进行更改,例如更改应用程序主题。

ContextThemeWrapper.setTheme(int) 的文档说:

Set the base theme for this context. Note that this should be called before any views are instantiated in the Context (for example before calling setContentView(View) or inflate(int, ViewGroup)).

所以我的第一个想法是在用户更改首选项时重新启动应用程序 onResume()。但是我注意到,有时重新启动 activity 的过程是无缝的,而其他时候 activity 关闭,可以看到主屏幕,并且仅在几秒钟后应用程序再次打开。

我想知道是否有办法更改处理首选项更改。例如,在 onResume 之后更改主题而不重新启动 activity 或在用户使用首选项时在后台重新启动 activity。

处理这个问题的正确方法是什么?

假设您的 Preference 屏幕是 Activity,当用户导航到它时,MainActivity 处于 paused 状态(然后可能处于stopped 状态)。当用户导航回 MainActivity 时,将调用 onResume();在这里您可以相应地更改 MainActivity 的状态以反映已更改的首选项。

When a user opens preferences on my app he may make changes that mean I have to restart my MainActivity however I don't want to user to notice anything happened.

用户不会注意到任何事情,因为 activity 生命周期会处理。

任务 - 事件 1 主要 Activity (MA) TO 偏好 Activity (PA)

事件 2 偏好 Activity (PA)TO 主要 Activity

Activity 生命周期 - MA onPause() 到 PA onResume() ... PA onPause() 到 MA onResume()

 nor remove it from the back stack.

如果您希望从 backstack 恢复相同的 activity 而不是创建新的 MainActivity,可以使用 launchmodes

代码示例

intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
        startActivity(intent);

我们的应用程序提供了多个主题,我们已经尝试过从 onResume 或 onStart [restart activity case] 更新主题的方法,但是需要调用 onCreate() 方法来更新主题,您需要完成activity 并使用选定的主题重新创建它。

要点:重新创建新的 activity 可能会导致使用 activity 中的线程或异步任务从网络获取的数据丢失,因此您需要把这个问题也处理一下。

在我们的应用程序中,我们将所选主题的数量保存在共享首选项中,并在创建新 activity 时加载它。

完成并重新启动 activity

public static void changeToTheme(Activity activity, int theme) {
    sTheme = theme;
    activity.finish();

    activity.startActivity(new Intent(activity, activity.getClass()));
}

我假设您将用户选择的主题存储在应用程序偏好设置中。所以在你的 Activity 的 onCreate() 中,添加 setTheme().

public void onCreate(Bundle savedInstanceState) {
    setTheme(android.R.style.Theme); // or whatever theme you're using

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
}

但更改在 activity 重新启动后才会生效。因此,如果您需要立即应用主题更改,请在应用主题后调用 recreate()

// Might need to call them on getApplication() depending on Context
setTheme(userSelectedTheme);
recreate();

此外,与 一样,重新创建 activity 可能会导致使用 Threads/AsyncTasks 从网络获取的数据丢失,因此您也需要考虑到这一点。