【问题标题】:How to use specific styles with specific themes?如何使用具有特定主题的特定样式?
【发布时间】:2017-01-10 20:13:08
【问题描述】:

我正在尝试围绕样式和主题展开思考。我的应用目前只有一个主题:

<style name="WhiteTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
</style>

我也有很多不同视图的样式,像这样:

<style name="BodyText" parent="TextAppearance.AppCompat.Body1">
    <item name="android:textSize">14sp</item>
    <item name="android:textColor">@color/default_text_color</item>
</style>

...我这样使用:

<TextView
    ...
    android:textAppearance="@style/BodyText"/>

现在,如果我要创建一个新主题,例如 DarkTheme,我将如何确保所有引用 BodyText 作为其 TextAppearance 的 TextView 都指向新样式?

【问题讨论】:

    标签: android android-theme android-styles


    【解决方案1】:

    为您希望跨主题具有不同的资源创建一个属性。

    <attr name="someTextColor" format="color"/>
    

    现在在您的主题中,定义属性

    <style name="WhiteTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="someTextColor">@android:color/black</item>
    </style>
    
    <style name="DarkTheme" parent="Theme.AppCompat">
        <item name="someTextColor">@android:color/white</item>
    </style>
    

    现在你可以使用它们了。

    <style name="BodyText" parent="TextAppearance.AppCompat.Body1">
        <item name="android:textSize">14sp</item>
        <item name="android:textColor">?attr/someTextColor</item>
    </style>
    

    也可以从代码中获取attr

    /**
     * Returns color for attr from the {@link Theme}
     *
     * @param theme {@link Theme} to get int from
     * @param attr  Attribute of the int
     * @return dimension for attr from the {@link Theme}
     */
    @ColorInt
    public static int getColor(@NonNull final Theme theme, @AttrRes final int attr) {
        final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
        try {
            return array.getColor(0, Color.TRANSPARENT);
        } finally {
            array.recycle();
        }
    }
    

    或作为 ColorStateList

    /**
     * Returns {@link ColorStateList} for attr from the {@link Theme}
     *
     * @param theme {@link Theme} to get int from
     * @param attr  Attribute of the int
     * @return dimension for attr from the {@link Theme}
     */
    @Nullable
    public static ColorStateList getColorStateList(@NonNull final Theme theme,
            @AttrRes final int attr) {
        final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
        try {
            return array.getColorStateList(0);
        } finally {
            array.recycle();
        }
    }
    

    然后

    final int someTextColor = getColor(getTheme(), R.attr.someTextColor);
    // or
    final ColorStateList someTextColor = getColorStateList(getTheme(), R.attr.someTextColor);
    

    【讨论】:

    • 非常感谢!这正是我想要的。
    【解决方案2】:

    textview 的主题

     <style name="Theme1"  parent="Theme.AppCompat.Light.DarkActionBar" >
            <item name="android:textColor">@color/colorAccent</item>
            <item name="android:shadowDy">1</item>
            <item name="android:shadowRadius">0.7</item>
            <item name="android:textAppearance">@style/MyRedTextAppearance</item>
        </style>
    
        <style name="MyRedTextAppearance" >
            <item name="android:textColor">@color/colorAccent</item>
            <item name="android:shadowDy">1</item>
            <item name="android:shadowRadius">0.7</item>
        </style>
    
    
        <style name="Theme2"  parent="Theme.AppCompat.Light.Dialog" >
            <item name="android:textColor">@color/colorPrimaryDark</item>
            <item name="android:shadowDy">1</item>
            <item name="android:shadowRadius">0.7</item>
            <item name="android:textAppearance">@style/MyBlueTextAppearance</item>
        </style>
    
        <style name="MyBlueTextAppearance" >
            <item name="android:textColor">@color/colorPrimary</item>
            <item name="android:shadowDy">1</item>
            <item name="android:shadowRadius">0.7</item>
        </style>
    

    将使用的文本视图

    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@style/Theme1"
            android:text="Dummy"/>
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Dummy"
            style="@style/Theme2"/>
    

    【讨论】:

    • 你没有回答这个问题。如何为WhiteTheme 指定BodyText 样式以及与DarkTheme 一起使用的不同样式?
    • 感谢您的编辑。然而,它仍然没有回答如何使用不同的文本视图样式。 AFAIK,这会更改所有 TextView 的默认样式吗?如果我有十几种不同的 TextView 样式想要随主题一起更改怎么办?
    • 你可以有 tetxview 的样式
    • 在这种情况下,需要添加多个主题以及需要添加多个 textview 样式。
    • 如何在主题中使用多种 TextView 样式?如果文本视图有十几种样式,并且每种样式都必须随主题而变化,你是怎么做的?
    猜你喜欢
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多