动态检索声明到 "styles.xml" 中的自定义样式

Dynamically retrieve custom styles declared into "styles.xml"

在 Android Studio 中,我声明了一些带有自定义属性的自定义样式,例如以下两个:

<resources>

<!-- Base application theme. -->
<style name="AppThemeBlueDark" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/AppThemeBlueDarkColorPrimary</item>
    <item name="colorPrimaryDark">@color/AppThemeBlueDarkColorPrimaryDark</item>
    <item name="colorAccent">@color/AppThemeBlueDarkColorAccent</item>
    <item name="android:colorBackground">@color/AppThemeBlueDarkBackground</item>

    <item name="my_type">my_theme</item>
    <item name="my_id">0</item>
    <item name="my_name">Dark Blue</item>
    <item name="my_default">true</item>
</style>

<style name="AppThemeBlueLight" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/AppThemeBlueLightColorPrimary</item>
    <item name="colorPrimaryDark">@color/AppThemeBlueLightColorPrimaryDark</item>
    <item name="colorAccent">@color/AppThemeBlueLightColorAccent</item>
    <item name="android:colorBackground">@color/AppThemeBlueLightBackground</item>

    <item name="my_type">my_theme</item>
    <item name="my_id">1</item>
    <item name="my_name">Light Blue</item>
    <item name="my_default">false</item>
</style>

</resources>

现在我想创建一个 java 自定义 Class,它能够检索我定义的所有样式,而无需事先了解它们的数量和名称;类似于:

public class ThemeChanger {

// Populate myThemes
public void ThemeChanger() {
    TypedArray theme_res = R.style.getStyleNames();
}
}

}

显然,方法“getStyleNames()”纯属幻想!

这在某种程度上可行吗?

最终目标是创建一个通用的可重用 class,它将能够管理和更改应用程序的主题,只需将主题定义为标准 "styles.xml" 但具有这些自定义属性,无需如果我决定使用不同的 themes/names.

,则必须修改 class

非常感谢您的帮助。

不,你这样做是完全错误的。

在此处查看文档 - Create Custom View

你要做的一切都在这个link。完全按照它。您的自定义属性需要在 <declare-styleable> 范围内,您将通过代码中的 TypedArray 引用这些属性。

因此您需要逐字逐句地阅读此文档

我使用 java 反射找到了一个解决方案(也许不是最优雅的):

import java.lang.reflect.Field;

public class ThemeChanger {

ThemeChanger(Context context){
    Field[] myFields;
    String myFullNameStyle;
    String myNameStyle;

    // Get all styles using reflection
    myFields = R.style.class.getFields();
    // Drill in into single style resource
    for (int i=0; i<myFields.length; i++) {
        myFullNameStyle = myFields[i].toString();
        if (myFullNameStyle.length()>0) {
            int pos = myFullNameStyle.lastIndexOf('.');
            if (pos!=-1) {
                myNameStyle = myFullNameStyle.substring(pos + 1);
                myNameStyle = myNameStyle.replace('_', '.');
                int myStyleId = context.getResources().getIdentifier(myNameStyle, "style", context.getPackageName());
                if (myStyleId != 0) {
                    int myTypeId[] = {R.attr.my_type};
                    String myType = context.obtainStyledAttributes(myStyleId, myTypeId).getString(0);
                    if (myType == "my_theme") {
                        // Do all things with other custom attrs,
                        // like populating a array to use with a menù
                    }
                }
            }
        }
    }
}
}

无论如何,谢谢你的努力。