自定义属性
自定义属性:应用在自定义控件上,可以在布局文件中使用自己定义的属性
如:
工程目录如下:
属性定义如下:attrs.xml (定义了才能在布局文件中使用) 注意: 下面的原始属性定义指的就是这
一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;不清楚的可以google一把
<?xml version="1.0" encoding="utf-8"?> <!-- name自己随便定义 format的格式定义可以看安卓系统怎么定义的 方法见图: --> <resources> <!-- 声明属性集的名称 根据这个name来解析 --> <declare-styleable name="MyView_parser"> <!-- 声明一个属性 name是 test_id 类型为 整数类型 尺寸使用demension--> <attr name="test_id" format="integer"/> <!-- 声明一个属性 name是 test_msg 类型为 字符串类型 --> <attr name="test_msg" format="string"/> <!-- 声明一个属性 name是 test_bitmap 类型为 引用类型 引用资源id --> <attr name="test_bitmap" format="reference"/> </declare-styleable> </resources>
布局文件中的使用:activity_main.xml
<!-- 在布局文件中使用自定义属性的方法: 声明 xmlns 前面字段(http://schemas.android.com/apk/res)为固定的,后面为该工程的包名 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tangs="http://schemas.android.com/apk/res/com.example.zdysx" //声明的命名空间 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <!-- 在自己的控件上定义自己的属性 test_msg为属性名 等号后面就为属性值 --> <com.example.zdysx.MyView android:layout_width="wrap_content" android:layout_height="wrap_content" tangs:test_msg="布局中设置的文字" tangs:test_bitmap="@drawable/ic_launcher" /> </RelativeLayout>
java代码:MainActivity.java只是起个显示界面的作用:
MyView.java
/* 自定义属性:应用在自定义控件上,可以在布局文件中使用自己定义的属性 系统定义的属性文件位置为: \sdk\platforms\android-16\data\res\values/attrs.xml文件中 步骤: 1.在values文件夹中新建一个xml文件,有属性名:name 和 格式:format 2.在布局文件中使用自己定义的属性: 使用之前必须先声明命名空间,如: xmlns:tangs="http://schemas.android.com/apk/res/com.example.zdysx" 3.在自定义的view的构造方法中,通过解析AttributeSet对象,获得所需要的属性值 */ public class MyView extends View{ /** * 在布局文件中声明该视图会自动调用此构造方法 * @param context * @param attrs 对xml布局文件中该控件 解析后的集合(反射得到的) */ public MyView(Context context, AttributeSet attrs) { super(context, attrs); //得到布局文件中属性值的id 得到在xml布局文件中所有的属性值(包括不是自定义的,用的父类的也会得到) int count = attrs.getAttributeCount(); for (int i = 0; i <count; i++) { String name = attrs.getAttributeName(i);//为布局文件的name String value = attrs.getAttributeValue(i);//为上面name对应的属性值的id System.out.println("name:"+name+",value:"+value); }//name:test_msg,value:@2131034112 xml布局文件的id //这种方法不便于对数据的区分 System.out.println("========方法二============="); /* * 根据xml布局文件中的属性与定义的属性做比较,而得到xml布局文件中设置的属性的内容 */ //MyView_parser就为定义xml属性所起的名字(attrs.xml文件中) TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyView_parser); int taCount=ta.getIndexCount(); for (int i = 0; i <taCount; i++) { int itemId = ta.getIndex(i);//id,MyView_parser文件中item的id System.out.println("xml--itemId:"+itemId); switch(itemId){//能够跟原始定义的属性与xml布局文件中使用到的属性一一匹配的打印出id case R.styleable.MyView_parser_test_msg: int msgId=ta.getResourceId(itemId, -1);//文本没有id,所以输出结果为1 CharSequence text = ta.getText(itemId);//得到文本内容 System.out.println("msgId:"+msgId+"--布局文件设置的文本内容:"+text); break; case R.styleable.MyView_parser_test_bitmap: ta.getDrawable(itemId);//得到xml布局文件中设置的图片 int bitmapId=ta.getResourceId(itemId, -1);//图片的资源(R中的)id System.out.println("bitmapId:"+bitmapId); break; } }//这种方法就是通过获取原始定义的属性id与当前加载了这些属性的布局文件中的控件进行匹配 //结论:通过上面的方法,可以得到在布局文件里为自己的属性设置的内容,所以在java代码中将内容设置到对应的控件上就行了 System.out.println("=======方法三=========="); //将自定义的命名空间赋值过来 String namespace="http://schemas.android.com/apk/res/com.example.zdysx"; //得到这个命名空间里 属性名为"test_msg"的内容 (文本内容) String text=attrs.getAttributeValue(namespace, "test_msg"); //得到这个命名空间里 属性名为 "test_bitmap"的内容 (这里为图片id) int id = attrs.getAttributeResourceValue(namespace, "test_bitmap", -1); System.out.println("得到的数据,文本:"+text+", 图片id:"+id); } } //数据都得到了就可以设置到对应的控件上了,通过findviewByid找到控件就行,然后定义方法去设置就行,具体见自定义组合控件的使用)
自定义组合控件的使用
打印结果如下:
说明:第一种方法将view的layout_width也获取到了 这个并不是自定义的属性
第二种方法只获取到了自定义的属性值,根据原始定义的属性名去与布局中使用到的该属性名匹配而获取属性值
第三种方法是根据指定命名空间和属性名,获取对应属性值,(还挺方便的)
可见上面三种方法得到的图片的id一致.