向视图添加属性

自定义视图还可以采用可在 Android 布局资源文件中使用的自定义属性。要向自定义视图添加属性,你需要执行以下操作:

  1. 定义属性的名称和类型: 这是在 res/values/attrs.xml 内完成的(必要时创建它)。以下文件定义了笑脸的面部颜色的颜色属性和笑脸表情的枚举属性:

    <resources>
        <declare-styleable name="SmileyView">
            <attr name="smileyColor" format="color" />
            <attr name="smileyExpression" format="enum">
                <enum name="happy" value="0"/>
                <enum name="sad" value="1"/>
            </attr>
        </declare-styleable>
        <!-- attributes for other views -->
    </resources>
    
  2. 在布局中使用你的属性: 这可以在使用自定义视图的任何布局文件中完成。以下布局文件创建一个带有快乐黄色笑脸的屏幕:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_height="match_parent"
        android:layout_width="match_parent">
    
        <com.example.app.SmileyView
            android:layout_height="56dp"
            android:layout_width="56dp"
            app:smileyColor="#ffff00"
            app:smileyExpression="happy" />
    </FrameLayout>
    

    提示:自定义属性不适用于 Android Studio 2.1 及更早版本(以及可能的未来版本)中的 tools:前缀。在这个例子中,用 tools:smileyColor 替换 app:smileyColor 将导致 smileyColor 既不在运行时也不在设计时设置。

  3. 阅读你的属性: 这是在你的自定义视图源代码中完成的。以下的 SmileyView 片段演示了如何提取属性:

    public class SmileyView extends View {
        // ...
    
        public SmileyView(Context context) {
            this(context, null);
        }
    
        public SmileyView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public SmileyView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SmileyView, defStyleAttr, 0);
            mFaceColor = a.getColor(R.styleable.SmileyView_smileyColor, Color.TRANSPARENT);
            mFaceExpression = a.getInteger(R.styleable.SmileyView_smileyExpression, Expression.HAPPY);
            // Important: always recycle the TypedArray
            a.recycle();
    
            // initPaints(); ...
        }
    }
    
  4. (可选)添加默认样式: 通过添加具有默认值的样式并将其加载到自定义视图中来完成此操作。以下默认笑脸样式代表一个快乐的黄色样式:

    <!-- styles.xml -->
    <style name="DefaultSmileyStyle">
        <item name="smileyColor">#ffff00</item>
        <item name="smileyExpression">happy</item>
    </style>
    

    通过将它添加为 obtainStyledAttributes 调用的最后一个参数(参见步骤 3 中的代码),将其应用于我们的 SmileyView

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SmileyView, defStyleAttr, R.style.DefaultSmileyViewStyle);
    

    请注意,在膨胀的布局文件中设置的任何属性值(请参阅步骤 2 中的代码)都将覆盖默认样式的相应值。

  5. (可选)在主题中提供样式: 这是通过添加新样式引用属性来完成的,该属性可以在主题中使用并为该属性提供样式。这里我们简单地命名我们的引用属性 smileyStyle

    <!-- attrs.xml -->
    <attr name="smileyStyle" format="reference" />
    

    然后我们在我们的应用主题中提供样式(这里我们只重用步骤 4 中的默认样式):

    <!-- themes.xml -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="smileyStyle">@style/DefaultSmileyStyle</item>
    </style>