样式化复合视图

Noe*_*tin 5 android android-layout android-styles

我想创建一个复合项目并为它设置不同的样式,但是到目前为止我还没有看到如何使用单一样式实现它,我必须使用不同的样式.

为了说明我的问题,我将定义一个示例场景.想象一下,我有一个包含项目的列表,这些项目是用户,我有一个头像,一个用户名和一封电子邮件.我想在我的主题上为每个3种不同的风格设置风格.

我想要实现的目标:

(文件res/layout/item_user.xml,这将为ListView膨胀)

<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>
Run Code Online (Sandbox Code Playgroud)

(文件res/values/styles.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>
Run Code Online (Sandbox Code Playgroud)

我实际上要做什么

(文件res/layout/item_user.xml,这将为ListView膨胀)

<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>
Run Code Online (Sandbox Code Playgroud)

(文件res/values/styles.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>
Run Code Online (Sandbox Code Playgroud)

如您所见,第二种情况暗示如果我想要更改项目的整个样式,我必须为每个视图单独执行.我想只改变顶级风格.

Hen*_*nry 0

您可以为此定义自定义主题属性。然后,视图将仅引用主题属性,您可以通过更改主题属性值来更改样式。

首先在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>
Run Code Online (Sandbox Code Playgroud)

然后在您的主题中定义它们:

<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
    <item name="avatarStyle">@style/CustomStyleA.Avatar</item>
    <item name="usernameStyle">@style/CustomStyleA.Username</item>
    ...
</style>
Run Code Online (Sandbox Code Playgroud)

并像这样引用它们:

<ImageView
    style="?avatarStyle"
    android:id="@+id/avatar"
    android:src="@drawable/avatar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
Run Code Online (Sandbox Code Playgroud)