什么是AttributeSet,我如何使用它?

83

什么是Android中的AttributeSet?

我如何在自定义视图中使用它?


2
@oae,那个链接已经失效了。 - Ky -
4个回答

34

虽然晚了些,但为其他人提供详细描述。

AttributeSet(Android文档)

一组属性,如在XML文档中与标记相关联所发现的属性。

基本上,如果您正在尝试创建自定义视图,并且想要通过AttributeSet传递诸如尺寸、颜色等值,那么您可以这样做。

这里有一个例子

想象一下您想创建如下的View

输入图像描述

其中有一个黄色背景的矩形和一个圆形,在矩形内部,其半径为5dp,背景为绿色。如果您希望通过XML使您的视图接受背景颜色和半径值,就像这样:

<com.anjithsasindran.RectangleView
    app:radiusDimen="5dp"
    app:rectangleBackground="@color/yellow"
    app:circleBackground="@color/green" />

那就是 AttributeSet 的使用场景。你可以在值文件夹中拥有名为 attrs.xml 的文件,并具备以下属性。

<declare-styleable name="RectangleViewAttrs">
    <attr name="rectangle_background" format="color" />
    <attr name="circle_background" format="color" />
    <attr name="radius_dimen" format="dimension" />
</declare-styleable>

因为这是一个视图,所以Java类需要继承自View

public class RectangleView extends View {

    public RectangleView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.RectangleViewAttrs);
        mRadiusHeight = attributes.getDimensionPixelSize(R.styleable.RectangleViewAttrs_radius_dimen, getDimensionInPixel(50));
        mCircleBackgroundColor = attributes.getDimensionPixelSize(R.styleable.RectangleViewAttrs_circle_background, getDimensionInPixel(20));
        mRectangleBackgroundColor = attributes.getColor(R.styleable.RectangleViewAttrs_rectangle_background, Color.BLACK);
        attributes.recycle()
    }
}

现在我们可以在XML布局中为RectangleView使用这些属性,并在RectangleView构造函数中获取这些值。

app:radius_dimen
app:circle_background
app:rectangle_background

2
你为什么在 getDimensionInPixel(50) 中提供了一个整数值? - Daksh Gargas
2
感谢您的精彩回答,易于理解。为了贡献这个答案,需要提供一些小信息,这将更有用。在完成后,请回收TypedArray。这将使它可以被后续调用者重复使用。 - Muhammed Yalçın Kuru
@MuhammedYalçınKuru 好建议,我已经进行了更改。 - capt.swag

8
您可以使用AttributeSet获取视图中您在xml中定义的自定义值。例如,有一个有关“定义自定义属性”的教程指出,“可以直接从AttributeSet中读取值”,但它没有说明如何实际操作。然而,它确实警告说,如果您不使用样式属性,则会发生以下情况:
  • 属性值中的资源引用未解析
  • 样式未应用
如果您想忽略整个样式属性并直接获取属性,请参考以下示例:

example.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:custom="http://www.chooseanything.org">

  <com.example.CustomTextView
    android:text="Blah blah blah"
    custom:myvalue="I like cheese"/>

</LinearLayout>

请注意,有两行xmlns(xmlns = XML命名空间),第二行定义为xmlns:custom。然后在其下面定义了custom:myvalue。
CustomTextView.java
public CustomTextView( Context context, AttributeSet attrs )
{
  super( context, attrs );
  String sMyValue = attrs.getAttributeValue( "http://www.chooseanything.org", "myvalue" );
  // Do something useful with sMyValue
}

6

AttributeSet是在xml资源文件中指定的属性集。在自定义视图中,您不需要进行任何特殊操作。 View(Context context, AttributeSet attrs)会被调用以从布局文件初始化视图。只需将此构造函数添加到自定义视图中即可。请查看SDK中的Custom View示例以查看其用法。


1
不确定示例链接是否真正显示了实际示例,但它们总是重定向到同一页面。我通常会从SDK中的示例文件夹引用相同示例。例如,上面引用的示例位于android-sdk\samples\android-17\ApiDemos\src\com\example\android\apis\view文件夹中。 - Sundeep

0

当从XML布局创建视图时,会从资源包中读取XML标记中的所有属性,并将它们作为AttributeSet传递给视图的构造函数

尽管可以直接从AttributeSet读取值,但这样做有一些缺点:

  • 不解析属性值中的资源引用
  • 不应用样式

取而代之的是,将AttributeSet传递给obtainStyledAttribute()。该方法返回已经被解除引用和设置样式的值的TypedArray数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接