视图中的多个样式值

时间:2010-11-23 04:33:20

标签: android

我在styles.xml中定义了2个样式。我想将它应用于textview。如何使用style =“@ style /”

实现它

6 个答案:

答案 0 :(得分:42)

你做不到。您必须创建一种结合了两种样式的样式。 (或者只创建一个继承自其中一个样式的样式,并添加第二个样式的额外数据)。

答案 1 :(得分:18)

您可以制作一种继承其他风格的风格

例如:

<style name="Side_Menu_Button" parent="android:attr/buttonStyleSmall">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">match_parent</item>
</style>

side_menu_button继承自buttonStyleSmall的所有属性

答案 2 :(得分:2)

作为一种在某些情况下可以使用的解决方法,您可以使用LinearLayout包装目标视图,并将另一种样式分配给另一个样式到视图:

<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  style="@style/padding">

  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Bold text with padding"
    style="@style/text_bold" />

</LinearLayout>

答案 3 :(得分:1)

这是我开始工作的一个黑客:

<style name="TextAppearance.Title.App" parent="TextAppearance.AppCompat.Subhead">
    <item name="android:textColor">@color/primary_text_default_material_light</item>
</style>

<style name="Custom.TV" parent="TextView.App">
    <item name="android:textAppearance">@style/TextAppearance.Other.App</item>
</style>

答案 4 :(得分:0)

对于支持textAttribute属性的Button和其他视图的特定情况,您可以将两个样式划分为一个Button特定样式,该样式将分配给attribute:style和一个Text特定样式,该样式将分配给{{ 1}}。但请注意,attribute:textAppearance中定义的属性将覆盖attribute:style中定义的值。

答案 5 :(得分:0)

我知道我迟到了 10 年,但我自己遇到了这个问题,并找到了解决方案,尽管这是一个很好的解决方法。

首先,您需要声明可样式化的属性,以便稍后分配给您的视图

<declare-styleable name="TextView">
    <attr name="style1" format="reference" />
    <attr name="style2" format="reference" />
    <attr name="style3" format="reference" />
    <attr name="style4" format="reference" />
    <attr name="style5" format="reference" />
</declare-styleable>

您可以将这些样式属性添加到布局中的视图中,例如

<TextView
    android:id="@+id/button_1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/nice_cta"
    app:style1="@style/Background_Blue"
    app:style2="@style/CallToAction.Primary"
    app:style3="@style/Button_Layout" />

要使其工作,您需要实现一个自定义 ViewInflater,您将其分配给 viewInflaterClass 下的应用程序主题。在此 ViewInflater 中,您收集可样式化的属性并将它们合并为一个 theme,如下所示:

class MultiStyleViewInflater : MaterialComponentsViewInflater() {
    // override the creators of any view you want to have multiple styles
    override fun createTextView(context: Context, attrs: AttributeSet?): AppCompatTextView {
        // create context if needed and set the attributes as usual
        return super.createTextView(createContextIfMultiStyle(context, attrs), attrs)
    }
    
    // override fun anyOtherView as needed ...

    private fun createContextIfMultiStyle(context: Context, attrs: AttributeSet?): Context {
        // get our handy custom attributes
        val styleAttributes = context.obtainStyledAttributes(attrs, R.styleable.TextView)
        
        // collect the styles added to the view
        val styles = extractStyles(styleAttributes)
        
        // create the custom ContextThemeWrapper only if the view has a custom multi style attribute
        val createdContext = if (styles.any { it != 0 }) {     
            // create a theme, add styles and create the wrapper using the theme
            val theme = context.resources.newTheme()
            
            theme.applyValidStyles(styles)
            ContextThemeWrapper(context, theme)  
        } else {
            // or just return the original context
            context
        }
        
        // don't forget to call this!
        styleAttributes.recycle()
        
        return createdContext
    }

    private fun extractStyles(styleAttributes: TypedArray) = listOf(
        // the zero values help us determine if we have a custom style added at all
        styleAttributes.getResourceId(R.styleable.TextView_style1, 0),
        styleAttributes.getResourceId(R.styleable.TextView_style2, 0),
        styleAttributes.getResourceId(R.styleable.TextView_style3, 0),
        styleAttributes.getResourceId(R.styleable.TextView_style4, 0),
        styleAttributes.getResourceId(R.styleable.TextView_style5, 0)
    )

    private fun Resources.Theme.applyValidStyles(styles: List<Int>) {
        // adding styles that actually exist. note we force update duplicate attributes
        styles.filterNot { it == 0 }.forEach { this.applyStyle(it, true) }
    }
}

要使其成为您的应用主题的 ViewInflater,请在其中添加以下行:

<item name="viewInflaterClass">com.agostonr.multistyleapp.utils.MultiStyleViewInflater</item>

此后,如果您构建应用程序,样式应显示在编辑器以及设备上正在运行的应用程序中。

有关更详细的解释,请参阅我写的关于它的文章 on Medium