Android 自定义属性详解

时间:2021-08-05 05:34:19

Android 自定义属性详解

在自定义属性时,需要在declare-styable节点下添加attr,名称以name定义,类型以format定义。

1、format取值

  • reference(引用值)
  • color(颜色值)
  • boolean (布尔值)
  • dimension (尺寸值)
  • float(浮点值)
  • integer(整型值)
  • string(字符串)
  • fraction(百分数值)
  • enum(枚举)
  • flag(位)

2、attrs.xml文件

自定义AttrTextView,使用所有类型的属性,最后的attrMulti为组合类型。
<declare-styleable name="AttrTextView">
<attr name="attrReference" format="reference" />
<attr name="attrColor" format="color" />
<attr name="attrBoolean" format="boolean" />
<attr name="attrDimension" format="dimension" />
<attr name="attrFloat" format="float" />
<attr name="attrInteger" format="integer" />
<attr name="attrString" format="string" />
<attr name="attrFraction" format="fraction" />
<attr name="attrEnum" >
<enum name="east" value="1" />
<enum name="west" value="2" />
<enum name="south" value="3" />
<enum name="north" value="4" />
</attr>
<attr name="attrMulti" format="string|reference" />
</declare-styleable>

3、布局文件activity_attr.xml

tv1的控件中罗列了所有了属性,tv2的控件显示fraction属性可以用两种方式定义,tv3和tv4显示了组合类型可以两种不同的方式。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<com.blog.demo.control.ui.AttrView
android:id="@+id/tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:attrReference="@string/app_name"
app:attrColor="#ffff0000"
app:attrBoolean="true"
app:attrDimension="15dp"
app:attrFloat="1.43"
app:attrInteger="36"
app:attrString="This is a String"
app:attrFraction="50%"
app:attrEnum="south" />

<com.blog.demo.control.ui.AttrView
android:id="@+id/tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:attrFraction="50%p" />

<com.blog.demo.control.ui.AttrView
android:id="@+id/tv3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:attrMulti="This is a String" />

<com.blog.demo.control.ui.AttrView
android:id="@+id/tv4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:attrMulti="@string/app_name" />

</LinearLayout>

4、自定义控件AttrView

在控件中,我们分别用不同的方法来获取属性的值。
需要注意的是enum类型可以用整型的方法获取。
而百分数值有两种方式,在方法getFraction(int index, int base, int pbase, float defValue)中,如果值是50%,使用base*0.5。一旦定义为50%p,则使用pbase*0.5。
最后组合类型需要调用一些特殊方法。

public class AttrView extends TextView {

public AttrView(Context context) {
this(context, null);
}

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

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

int resId = a.getResourceId(R.styleable.AttrTextView_attrReference, 0);
int color = a.getColor(R.styleable.AttrTextView_attrColor, 0);
boolean bool = a.getBoolean(R.styleable.AttrTextView_attrBoolean, false);
int dimen = a.getDimensionPixelSize(R.styleable.AttrTextView_attrDimension, 0);
float f = a.getFloat(R.styleable.AttrTextView_attrFloat, 0);
int i = a.getInteger(R.styleable.AttrTextView_attrInteger, 0);
float fraction = a.getFraction(R.styleable.AttrTextView_attrFraction, 100, 200, 0);
int e = a.getInt(R.styleable.AttrTextView_attrEnum, 0);

CharSequence multi = a.getText(R.styleable.AttrTextView_attrMulti);

a.recycle();

String text = (resId != 0 ? "ref = " + getResources().getString(resId) + "\n" : "") +
(color != 0 ? "color:" + color + "\n" : "") +
(bool ? "bool = true\n" : "") +
(dimen != 0 ? "dimen = " + dimen + "\n" : "") +
(f != 0 ? "float = " + f + "\n" : "") +
(i != 0 ? "integer = " + i + "\n" : "") +
(fraction != 0 ? "fraction = " + fraction + "\n" : "") +
(e != 0 ? "enum = " + e + "\n" : "") +
(multi != null ? "multi = " + multi + "\n" : "");
setText(text);
}

}

5、显示结果如下

Android 自定义属性详解