从片段中更改 activity 主题

Changing the activity theme from within the fragment

我先介绍一下我的代码。查看主题:

<resources>

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:textAllCaps">false</item>
        <item name="android:windowEnableSplitTouch">false</item>
    </style>


    <style name="AppTheme.Launcher">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:windowBackground">@drawable/launch_screen</item>
    </style>
</resources>

AppTheme.Launcher 用于让用户收到 "splash screen" 的问候。在 MainActivity onCreate 函数中,我使用 setTheme(R.style.AppTheme) 更改主题,我还使用 supportActionBar?.hide() 隐藏操作栏。我的应用程序是面向片段的。我只有一个 Activity 承载有多个片段的导航方案。问题出在这里:

    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>

在我的一个片段中,我想再次显示操作栏,我不希望我的状态栏再是半透明的,或者换句话说,我希望它能被看到并具有颜色 PrimaryDark。为此,我在 MainActivity 中编写了一个函数。

    fun clearTranslucent() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val w: Window = window
            w.clearFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
            )
            w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
        }
    }

这就是乐趣的开始。出于某种原因,这个白色 space 被添加在两者之间。如果我决定注释掉这一行 WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,结果会更加奇怪。状态栏变成 grayed 并且我的 ScrollView 停止工作。当我想更改 Activity 的原始主题时,我在几个片段中出现了同样的错误。我试过从片段中更改主题,但它不起作用。在某处阅读,您只能从 onCreate 函数中更改 Activity 主题。为什么我的布局不正常?

您描述的问题是已知错误。

您只能在 activity 的 onCreate 发生之前设置 activity 的主题

所以你有两个选择:

  1. 用上述片段打开一个新的activity,并在 android 清单。

  2. 在你的fragment中设置activity的主题,然后在oncreate中编写显示你的fragment的逻辑,当你改变 主题,调用 activity.recreate() 这将使 activity 重新启动并应用您的主题。