Android-AttributeSet详解

一、概述

AttributeSet是Android中一个十分重要的类,它是Android View对象在xml布局文件中定义的属性集合。在LayoutInflater解析xml文件时,会将xml定义的属性集合转化成AttributeSet对象,并将该对象传递给View对象构造方法。因此,在自定义View或者对已有View进行定制时,了解AttributeSet的用法是非常必要的。

二、AttributeSet的常用方法

1. getAttributeCount()

获取AttributeSet中属性的个数。

2. getAttributeName()

获取指定位置的属性名称。

3. getAttributeValue()

获取指定位置的属性值。

4. getAttributeValueNS()

根据给定的命名空间和属性名称,获取属性值。

5. getAttributeBooleanValue()

获取指定位置的布尔类型属性的值。

6. getAttributeIntValue()

获取指定位置的整型属性的值。

7. getAttributeFloatValue()

获取指定位置的浮点型属性的值。

8. getAttributeListValue()

获取指定位置的多选属性的值。

9. getAttributeResourceValue()

获取指定位置的资源类型属性的值。

10. getAttributeValueInt()

获取指定名称的整型属性的值。

11. getAttributeValueFloat()

获取指定名称的浮点型属性的值。

12. getAttributeValueBoolean()

获取指定名称的布尔型属性的值。

13. getAttributeValueColor()

获取指定名称的颜色类型属性的值。

14. getAttributeValueDimension()

获取指定名称的尺寸类型属性的值。

15. getAttributeValueString()

获取指定名称的字符串类型属性的值。

三、AttributeSet的使用方法

在Android中,通常是通过xml文件定义View的属性,并在代码中通过LayoutInflater.inflate()或View的构造方法 向View传递xml文件的属性。LayoutInflater.inflate()方法的使用方法如下:

View view = LayoutInflater.from(context).inflate(layoutId, parent, false);

其中layoutId是对应的xml布局文件的id,parent是ViewGroup的实例,表示要将View添加到哪个容器中。inflate()方法会将xml文件中定义的所有属性转化成AttributeSet,并将这个对象传递给View的构造方法。

除了在xml文件中传递属性,还可以在代码中直接创建AttributeSet对象:

AttributeSet attrs = new AttributeSet() {

@Override

public int getAttributeCount() {

return 0;

}

@Override

public String getAttributeName(int index) {

return null;

}

@Override

public String getAttributeValue(int index) {

return null;

}

@Override

public String getAttributeValue(String namespace, String name) {

return null;

}

@Override

public String getPositionDescription() {

return null;

}

@Override

public int getAttributeNameResource(int index) {

return 0;

}

@Override

public int getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue) {

return 0;

}

@Override

public int getAttributeListValue(int index, String[] options, int defaultValue) {

return 0;

}

@Override

public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {

return 0;

}

@Override

public int getAttributeUnsignedIntValue(int index, int defaultValue) {

return 0;

}

@Override

public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) {

return 0;

}

@Override

public float getAttributeFloatValue(int index, float defaultValue) {

return 0;

}

@Override

public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {

return 0;

}

@Override

public int getAttributeIntValue(int index, int defaultValue) {

return 0;

}

@Override

public int getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue) {

return 0;

}

@Override

public boolean getAttributeBooleanValue(int index, boolean defaultValue) {

return false;

}

@Override

public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {

return 0;

}

@Override

public int getAttributeResourceValue(int index, int defaultValue) {

return 0;

}

@Override

public int getAttributeListValue(int index, String[] options) {

return 0;

}

@Override

public boolean getAttributeValueBoolean(String namespace, String attribute, boolean defaultValue) {

return false;

}

@Override

public boolean getAttributeValueBoolean(int index, boolean defaultValue) {

return false;

}

@Override

public int getAttributeValueColor(String namespace, String attribute, int defaultValue) {

return 0;

}

@Override

public int getAttributeValueColor(int index, int defaultValue) {

return 0;

}

@Override

public float getAttributeValueDimension(String namespace, String attribute, float defaultValue) {

return 0;

}

@Override

public float getAttributeValueDimension(int index, float defaultValue) {

return 0;

}

@Override

public int getAttributeValueInt(String namespace, String attribute, int defaultValue) {

return 0;

}

@Override

public int getAttributeValueInt(int index, int defaultValue) {

return 0;

}

@Override

public int getAttributeUnsignedShortValue(String namespace, String attribute, int defaultValue) {

return 0;

}

@Override

public int getAttributeUnsignedShortValue(int index, int defaultValue) {

return 0;

}

@Override

public String getClassAttribute() {

return null;

}

@Override

public int getIdAttributeResourceValue(int defaultValue) {

return 0;

}

@Override

public String getIdAttribute() {

return null;

}

@Override

public int getStyleAttribute() {

return 0;

}

};

然而这样创建的AttributeSet并没有任何实际作用。

在自定义View的时候,需要继承一些系统提供好的Widget,而这些控件将有些属性不能够通过xml文件定义,只能在代码中修改。例如继承TextView控件,则需要通过构造函数添加TextAppearance属性:

public class MyTextView extends TextView {

public MyTextView(Context context, AttributeSet attrs) {

super(context, attrs);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);

int textAppearance = a.getResourceId(R.styleable.MyTextView_textAppearance, 0);

if (textAppearance != 0) {

setTextAppearance(context, textAppearance);

}

a.recycle();

}

}

这段代码中,我们通过context.obtainStyledAttributes()方法创建了一个TypedArray对象。其第一个参数是AttributeSet,第二个参数是我们自定义属性的定义。然后我们通过TypedArray.getResourceId()获取属性值。获取完属性值之后需要对TypedArray进行回收,以便下次使用。

在xml布局文件中设置的属性如果没有在自定义属性中定义,setAttribute()方法不会设置该属性。

四、案例说明

1.在xml文件中定义了一个自定义控件属性,然后在代码中获取它的值,做相应的处理。

在xml文件中定义自定义属性:

在自定义Layout类中,构造函数中获取backgroundColor属性:

public class MyLayout extends LinearLayout {

private int backgroundColor;

public MyLayout(Context context) {

this(context, null);

}

public MyLayout(Context context, AttributeSet attrs) {

super(context, attrs);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyLayout);

backgroundColor = a.getColor(R.styleable.MyLayout_backgroundColor, Color.TRANSPARENT);

a.recycle();

}

public void setBackgroundColor(int backgroundColor) {

this.backgroundColor = backgroundColor;

this.invalidate();

}

public int getBackgroundColor() {

return backgroundColor;

}

}

2.自定义一个圆形ImageView控件,设置borderwidth和bordercolor两个属性,代码中获取并处理这两个属性。

在xml文件中定义自定义属性:

在自定义View的构造方法中需要获取这两个属性:

public class CircleImageView extends ImageView {

private float borderWidth;

private int borderColor;

public CircleImageView(Context context) {

super(context);

}

public CircleImageView(Context context, AttributeSet attrs) {

super(context, attrs);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView);

borderWidth = a.getDimension(R.styleable.CircleImageView_borderWidth, 0);

borderColor = a.getColor(R.styleable.CircleImageView_borderColor, Color.BLACK);

a.recycle();

}

//...

}

当然,在自定义控件中,还需要重写onDraw()方法,在绘制图片的时候添加边框。如果图片大小不是一个正方形,则需要在圆的内部绘制该图片,因此需要获取圆的半径和x、y坐标。具体实现可以在网上找到。

壹涵网络我们是一家专注于网站建设、企业营销、网站关键词排名、AI内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。

我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!

点赞(94) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部