我在styles.xml中定义了2个样式。我想将它应用于textview。如何使用style =“@ style /”
实现它答案 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。