我想创建一个复合项目并为其提供不同的样式,但到目前为止,我不知道如何使用单一样式来实现它,我必须使用不同的样式。
为了说明我的问题,我将定义一个示例方案。想象一下,我有一个包含项目的列表,这些项目是用户,我有一个头像、一个用户名和一个电子邮件。我想在我的主题上设计这 3 个不同的风格。
我想要实现的目标:
(文件 res/layout/item_user.xml,这将为列表视图膨胀)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
style="@style/CustomStyleA">
<ImageView
style="avatarStyle"
android:id="@+id/avatar"
android:src="@drawable/avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
style="usernameStyle"
android:id="@+id/username"
android:text="Username"
android:layout_toRightOf="@id/avatar"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
style="emailStyle"
android:id="@+id/email"
android:text="fakemail@mail.com"
android:layout_toRightOf="@id/avatar"
android:layout_below="@id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
(文件 res/值/样式.xml)
<resources>
<!-- Style A -->
<style name="CustomStyleA">
<item name="avatarStyle">@style/CustomStyleA.Avatar</item>
<item name="usernameStyle">@style/CustomStyleA.Username</item>
<item name="emailStyle">@style/CustomStyleA.Email</item>
</style>
<style name="CustomStyleA.Avatar">
<!-- Here avatar specific styles -->
</style>
<style name="CustomStyleA.Username" parent="android:TextAppearance">
<!-- Here username specific styles -->
</style>
<style name="CustomStyleA.Email" parent="android:TextAppearance">
<!-- Here email specific styles -->
</style>
<!-- Style B -->
<style name="CustomStyleB">
<item name="avatarStyle">@style/CustomStyleB.Avatar</item>
<item name="usernameStyle">@style/CustomStyleB.Username</item>
<item name="emailStyle">@style/CustomStyleB.Email</item>
</style>
<style name="CustomStyleB.Avatar">
<!-- Here avatar specific styles -->
</style>
<style name="CustomStyleB.Username" parent="android:TextAppearance">
<!-- Here username specific styles -->
</style>
<style name="CustomStyleB.Email" parent="android:TextAppearance">
<!-- Here email specific styles -->
</style>
</resources>
我实际上必须做什么
(文件 res/layout/item_user.xml,这将为列表视图膨胀)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content">
<ImageView
style="@style/CustomStyleA.Avatar"
android:id="@+id/avatar"
android:src="@drawable/avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
style="@style/CustomStyleA.Email"
android:id="@+id/username"
android:text="Username"
android:layout_toRightOf="@id/avatar"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
style="@style/CustomStyleA.Email"
android:id="@+id/email"
android:text="fakemail@mail.com"
android:layout_toRightOf="@id/avatar"
android:layout_below="@id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
(文件 res/值/样式.xml)
<resources>
<!-- Style A -->
<style name="CustomStyleA.Avatar">
<!-- Here avatar specific styles -->
</style>
<style name="CustomStyleA.Username" parent="android:TextAppearance">
<!-- Here username specific styles -->
</style>
<style name="CustomStyleA.Email" parent="android:TextAppearance">
<!-- Here email specific styles -->
</style>
<!-- Style B -->
<style name="CustomStyleB.Avatar">
<!-- Here avatar specific styles -->
</style>
<style name="CustomStyleB.Username" parent="android:TextAppearance">
<!-- Here username specific styles -->
</style>
<style name="CustomStyleB.Email" parent="android:TextAppearance">
<!-- Here email specific styles -->
</style>
</resources>
如您所见,第二种情况意味着,如果我想更改项目的整个样式,则必须为每个视图单独执行此操作。我只想更改顶部样式。
您可以为此定义自定义主题属性。然后,视图将仅引用主题属性,您可以通过更改主题属性值来更改样式。
首先在 res/values/attrs 中声明自定义主题属性.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomAttributes">
<attr name="avatarStyle" format="reference" />
<attr name="usernameStyle" format="reference" />
...
</declare-styleable>
</resources>
然后在您的主题中定义它们:
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="avatarStyle">@style/CustomStyleA.Avatar</item>
<item name="usernameStyle">@style/CustomStyleA.Username</item>
...
</style>
并像这样引用它们:
<ImageView
style="?avatarStyle"
android:id="@+id/avatar"
android:src="@drawable/avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
这可以通过定义您自己的主题和您自己的属性来实现。
这是你的styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
<!-- Style A -->
<style name="CustomStyleA" parent="AppTheme">
<item name="avatarStyle">@style/CustomStyleA.Avatar</item>
<item name="usernameStyle">@style/CustomStyleA.Username</item>
<item name="emailStyle">@style/CustomStyleA.Email</item>
</style>
<!-- Style B -->
<style name="CustomStyleB" parent="AppTheme">
<item name="avatarStyle">@style/CustomStyleB.Avatar</item>
<item name="usernameStyle">@style/CustomStyleB.Username</item>
<item name="emailStyle">@style/CustomStyleB.Email</item>
</style>
<style name="CustomStyleA.Avatar">
<!-- Here avatar specific styles -->
</style>
<style name="CustomStyleA.Username" parent="android:TextAppearance">
<!-- Here username specific styles -->
<item name="android:textColor">@android:color/holo_red_dark</item>
</style>
<style name="CustomStyleA.Email" parent="android:TextAppearance">
<!-- Here email specific styles -->
</style>
<style name="CustomStyleB.Avatar">
<!-- Here avatar specific styles -->
</style>
<style name="CustomStyleB.Username" parent="android:TextAppearance">
<!-- Here username specific styles -->
<item name="android:textColor">@android:color/holo_blue_dark</item>
</style>
<style name="CustomStyleB.Email" parent="android:TextAppearance">
<!-- Here email specific styles -->
</style>
</resources>
avatarStyle,usernameStyle,emailStyle是我们从未定义的属性。因此,让我们在 attrs.xml
中定义我们的属性。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--<declare-styleable name="AppTheme">-->
<attr name="avatarStyle" format="reference"/>
<attr name="usernameStyle" format="reference"/>
<attr name="emailStyle" format="reference"/>
<!--</declare-styleable>-->
</resources>
以及您提到的布局layout/item_user.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
>
<ImageView
style="?attr/avatarStyle"
android:id="@+id/avatar"
android:src="@drawable/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
style="?attr/usernameStyle"
android:id="@+id/username"
android:text="Username"
android:layout_toRightOf="@id/avatar"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
style="?attr/emailStyle"
android:id="@+id/email"
android:text="fakemail@mail.com"
android:layout_toRightOf="@id/avatar"
android:layout_below="@id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
您只需在AndroidManifest.xml
文件中切换活动代码中的android:theme
属性即可。
android:theme="@style/CustomStyleB"