如何在运行时将可更改的主题应用到用户界面?

3
我的应用程序用户有更改应用程序主题的可能性。您可以在Play Store中查看:https://play.google.com/store/apps/details?id=at.guger.musixs 到目前为止,每个Activity都覆盖了onApplyThemeResource方法。这非常耗费时间,但是由于每个活动都有自己的特点,例如该活动没有ActionBar,因此无法以一种方式完成。
还有一个问题。这些样式不适用于AlertDialogs,如果您检查我的应用程序,则会看到这一点!
那么是否有更好的应用样式的方法?我看到了一个名为AppThemeEngine的模块,它能够处理主题,但是需要超级用户权限,因此对于普通客户来说是无用的。
@Override
protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
    super.onApplyThemeResource(theme, resid, first);

    mPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

    int iThemeID = R.style.NoActionBarThemeBlue;

    String sPrefBlue = getResources().getString(R.string.pref_color_blue);
    String sPrefGray = getResources().getString(R.string.pref_color_gray);
    String sPrefGreen = getResources().getString(R.string.pref_color_green);
    String sPrefOrange = getResources().getString(R.string.pref_color_orange);
    String sPrefRed = getResources().getString(R.string.pref_color_red);

    String sPrefColor = mPreferences.getString(getResources().getString(R.string.keyThemeColor), sPrefBlue);

    if (sPrefColor.equals(sPrefBlue)) {
        iThemeID = R.style.NoActionBarThemeBlue;
    }
    else if (sPrefColor.equals(sPrefGray)) {
        iThemeID = R.style.NoActionBarThemeGray;
    }
    else if (sPrefColor.equals(sPrefGreen)) {
        iThemeID = R.style.NoActionBarThemeGreen;
    }
    else if (sPrefColor.equals(sPrefOrange)) {
        iThemeID = R.style.NoActionBarThemeOrange;
    }
    else if (sPrefColor.equals(sPrefRed)) {
        iThemeID = R.style.NoActionBarThemeRed;
    }

    RuntimeInfo.setThemeID(iThemeID);

    theme.applyStyle(iThemeID, true);
}

我的styles.xml文件:

<resources>
    <style name="ActionBarThemeBlue" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowBackground">@android:color/white</item>
        <item name="colorPrimary">@color/bluePrimary</item>
        <item name="colorPrimaryDark">@color/bluePrimaryDark</item>
        <item name="colorAccent">@color/blueAccent</item>
    </style>

    <style name="NoActionBarThemeBlue" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@android:color/white</item>
        <item name="colorPrimary">@color/bluePrimary</item>
        <item name="colorPrimaryDark">@color/bluePrimaryDark</item>
        <item name="colorAccent">@color/blueAccent</item>
    </style>

    <style name="ActionBarThemeGray" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowBackground">@android:color/white</item>
        <item name="colorPrimary">@color/grayPrimary</item>
        <item name="colorPrimaryDark">@color/grayPrimaryDark</item>
        <item name="colorAccent">@color/grayAccent</item>
    </style>

    <style name="NoActionBarThemeGray" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@android:color/white</item>
        <item name="colorPrimary">@color/grayPrimary</item>
        <item name="colorPrimaryDark">@color/grayPrimaryDark</item>
        <item name="colorAccent">@color/grayAccent</item>
    </style>


    <style name="ActionBarThemeGreen" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowBackground">@android:color/white</item>
        <item name="colorPrimary">@color/greenPrimary</item>
        <item name="colorPrimaryDark">@color/greenPrimaryDark</item>
        <item name="colorAccent">@color/greenAccent</item>
    </style>

    <style name="NoActionBarThemeGreen" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@android:color/white</item>
        <item name="colorPrimary">@color/greenPrimary</item>
        <item name="colorPrimaryDark">@color/greenPrimaryDark</item>
        <item name="colorAccent">@color/greenAccent</item>
    </style>

    ...

</resources>

我希望有人知道更好的更改主题的方法!谢谢!

1个回答

0
这在以下的应用程序主题引擎下运作得非常好:

https://github.com/garretyoder/app-theme-engine

如果您想支持Android O,您需要下载库并将以下代码添加到ATE类的applyTaskDescription方法中:

if (icon == null) {
    Drawable mIconDrawable = activity.getApplicationInfo().loadIcon(activity.getPackageManager());
    if (mIconDrawable instanceof BitmapDrawable) {
        icon = ((BitmapDrawable)mIconDrawable).getBitmap();
    } else if (mIconDrawable instanceof AdaptiveIconDrawable) {
        icon = getBitmapFromDrawable(mIconDrawable);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接