1 自定义属性值
自定义view的起步是自定义属性,并且正确的读取属性。
在res/values/attrs.xml的文件中创建属性:
<declare-styleable name="ViewDemoAttr35"><attr name="string35" format="string"/><attr name="boolean35" format="boolean"/><attr name="color35" format="color"/><attr name="integer35" format="integer"/><attr name="enum35" format="enum"><enum name="enum0" value="0" /><enum name="enum1" value="1" /><enum name="enum2" value="2" /></attr><attr name="dimension35" format="dimension"/><attr name="float35" format="float"/><attr name="reference351" format="reference"/><attr name="reference352" format="reference"/><attr name="reference353" format="reference"/><attr name="reference354" format="reference"/><attr name="fraction35" format="fraction"/><attr name="bg351" format="color|reference"/><attr name="bg352" format="color|reference"/><attr name="flag35" ><flag name="flag1" value="1"/><flag name="flag2" value="2"/></attr></declare-styleable>
或者:
<!--属性声明--><attr name="demo1" format="string"/><!--属性使用--><declare-styleable name="MyTextView"><attr name="demo1"/></declare-styleable>
两种方式略有不同,第一种方式定义的属性只能在内部使用,第二种方式定义的属性作为公共属性,其他自定view也可以使用。
自定义属性需要name和format,name是属性的名字,format是属性的格式:
Android支持的属性格式包括:
string 属性取值为string,或者指向R.string.id 的一个资源color 属性取值为颜色,类似#cdcdcd,或者指向R.color.idboolean 属性取值为true或者falsedimension 属性取值为尺寸类型,例如px,sp,dp也可以指向一个R.dimen.idenum 属性指向具体的枚举值flag 属性指向一个flag类型,位运算,类似enum,float 属性指向一个floatfraction 属性指向一个百分数,只能是xx%样式的数据integer 属性指向一个int值reference 属性指向一个引用id,类似R.drawable.id
注意:
attr节点有两种子节点,enum和flag,enum和flag不能混合使用。
enum可在format声明,也可以不声明,当attr节点内有enum节点时,attr可以赋值为enum。
flag不可在format声明,当attr节点内有flag节点时,attr可以赋值为flag。
enum子节点的声明,value的值只能是int类型,且只能有一个值。
flag的声明,value也只能是int,但是可以利用|设置多个值。
还可以定义为 color|reference 一般用于颜色 @color/。
2 读取属性
自定义View需要实现三个构造函数(最好),属性就存储在attrs中,利用Context的obtainStyledAttributes方法得到TypedArray 对象进行属性获取,最后需要调用TypedArray 的recycle方法进行回收。
public ViewDemo35(Context context) {this(context,null);}public ViewDemo35(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public ViewDemo35(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);handleCustomAttrs(context,attrs);init();}private void handleCustomAttrs(Context context,AttributeSet attrs) {if (attrs == null) {return;}TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ViewDemoAttr35);String str = typedArray.getString(R.styleable.ViewDemoAttr35_string35);boolean boo = typedArray.getBoolean(R.styleable.ViewDemoAttr35_boolean35, false);int color1 = typedArray.getColor(R.styleable.ViewDemoAttr35_color35, Color.BLUE);int intege = typedArray.getInteger(R.styleable.ViewDemoAttr35_integer35, 10);int enum1 = typedArray.getInt(R.styleable.ViewDemoAttr35_enum35, 1);int size1 = typedArray.getDimensionPixelSize(R.styleable.ViewDemoAttr35_dimension35, 22);float float1 = typedArray.getFloat(R.styleable.ViewDemoAttr35_float35, 22);int resid1 = typedArray.getResourceId(R.styleable.ViewDemoAttr35_reference351, R.drawable.close_icon);int resid2 = typedArray.getResourceId(R.styleable.ViewDemoAttr35_reference352, R.color.black);Drawable drawable1 = typedArray.getDrawable(R.styleable.ViewDemoAttr35_reference353);int resid3 = typedArray.getResourceId(R.styleable.ViewDemoAttr35_reference354, positedst1);float fraction = typedArray.getFraction(R.styleable.ViewDemoAttr35_fraction35,1,1,0.1f);int color2 = typedArray.getColor(R.styleable.ViewDemoAttr35_bg351,R.drawable.gradientdemo);int color3 = typedArray.getColor(R.styleable.ViewDemoAttr35_bg352,R.drawable.background_tab);int int4 = typedArray.getInt(R.styleable.ViewDemoAttr35_flag35, 1);typedArray.recycle();}}
typeArray的getXXX函数的第一个参数组成styleable的name+_+属性name,例如.styleable.ViewDemoAttr35_fraction35,ViewDemoAttr35是styleable的名字,fraction35是属性名。
3如何使用
AS 下,布局文件根目录工具推荐的方法,只写一个命名空间
xmlns:app="/apk/res-auto,就可以包含所有的自定义属性,利用app:的前缀就可以使用所有的自定义属性了。
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayoutxmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".Main15Activity2"><com.ldx.canvasdrawdemo.LinearLayoutDemoandroid:id="@+id/view_group_demo"android:layout_width="match_parent"android:layout_height="100dp"android:orientation="vertical"><TextViewandroid:id="@+id/demo_tv1"android:layout_width="match_parent"android:layout_height="50dp"android:text="sjldjflsjfljs"/></com.ldx.canvasdrawdemo.LinearLayoutDemo><com.ldx.canvasdrawdemo.ViewDemo35android:layout_width="match_parent"android:layout_height="100dp"app:string35="string35"app:boolean35="true"app:color35="#cdcdcd"app:integer35="22"app:enum35="enum0"app:dimension35="25dp"app:float35="22"app:reference351 = "@drawable/ic_launcher_background"app:reference352 = "@drawable/shape_deep_blue"app:reference353 = "@drawable/have_icon"app:reference354 = "@drawable/image_home_game_nor2"app:fraction35 = "20%"app:bg351 = "@color/colorPrimary"app:bg352 = "@color/black"app:flag35 = "flag1" /></android.support.constraint.ConstraintLayout>