在运行时使用setTheme()仅更改文本颜色

时间:2018-10-16 21:56:44

标签: java android styles themes textcolor

我正在尝试为我的应用实现深色主题。用户可以在选项菜单中轻松地在正常和黑暗之间切换,效果很好。但是当在运行时更改主题时,只有文本颜色会更改,我不知道为什么。

styles.xml中我的黑暗主题:

<style name="Dark" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/dark_background</item>
    <item name="colorPrimaryDark">@color/dark_top</item>
    <item name="colorAccent">@color/dark_button</item>
    <item name="colorButtonNormal">@color/dark_button</item>
    <item name="android:colorBackground">@color/dark_background</item>
    <item name="android:itemBackground">@color/dark_background</item>
    <item name="android:textColor">@color/white</item>
    <item name="android:textColorHint">#EAEAEA</item>
    <item name="android:textColorPrimary">@color/white</item>
    <item name="android:textColorSecondary">@color/white</item>
    <item name="android:textColorTertiary">@color/white</item>
</style>

我设置样式的方式:

setTheme(R.style.Dark);

更改主题之前: before

更改主题后: after

我真的不知道为什么。是因为NavigationView吗?

1 个答案:

答案 0 :(得分:0)

确保在setTheme()之前调用setContentView()或使视图膨胀。根据{{​​3}},必须在上下文中实例化任何视图之前使用setTheme()。使用recreate()创建活动的新实例,以便可以在onCreate()方法中应用更改的主题。

稍稍搜索一下,您可以找到几个主题切换的示例。这是一个这样的示例的链接: documentation

如果我有多个活动需要使用该设置,我将使用PreferenceManager存储此类设置以便于访问。除非您已经有了更好的方法来存储用户的主题选择,否则我将建议以下示例。

MyAppPreferences类示例:

public class MyAppPreferences {

    private static SharedPreferences getPrefs(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context);
    }

    public static int getThemeId(Context context, int defaultThemeId) {
        return getPrefs(context).getInt("CurrentThemeId", defaultThemeId);
    }
    public static void setThemeId(Context context, int value) {
        getPrefs(context).edit().putInt("CurrentThemeId", value).commit();
    }

}

使用MyAppPreferences类的示例Activity类:

public class MyActivity extends AppCompatActivity implements OnClickListener {

    private Button btnDark;
    private Button btnLight;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);            
        // Set the theme
        // If there is nothing set, the light theme will be used by default
        setTheme(MyAppPreferences.getThemeId(this, R.style.Light));
        setContentView(R.layout.myLayout);

        btnDark = (Button) this.findViewById(R.id.viewbtnDark);
        btnDark.setOnClickListener(this);

        btnLight = (Button) this.findViewById(R.id.viewbtnLight);
        btnLight.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // 1. Set the theme preference
        // 2. Recreate the activity to "apply" the theme
        if (v.equals(btnDark)) {
            MyAppPreferences.setThemeId(this, R.style.Dark);
            this.recreate();
        } else if (v.equals(btnLight)) {
            MyAppPreferences.setThemeId(this, R.style.Light);
            this.recreate();
        }
    }

}

您的示例主题没有显示windowActionBar或windowNoTitle设置,因此,如果您碰巧正在使用默认主题,并且在深色主题中未以相同的方式设置这些选项,则可能仍然会崩溃。检查Logcat中是否存在以下错误:java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor.

黑暗主题示例

<style name="Dark" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/dark_background</item>
    <item name="colorPrimaryDark">@color/dark_top</item>
    <item name="colorAccent">@color/dark_button</item>
    <item name="colorButtonNormal">@color/dark_button</item>
    <item name="android:colorBackground">@color/dark_background</item>
    <item name="android:itemBackground">@color/dark_background</item>
    <item name="android:textColor">@color/white</item>
    <item name="android:textColorHint">#EAEAEA</item>
    <item name="android:textColorPrimary">@color/white</item>
    <item name="android:textColorSecondary">@color/white</item>
    <item name="android:textColorTertiary">@color/white</item>
</style>