Android自定义组合控件之自定义属性

时间:2022-07-27 20:40:54

自定义组合控件:

1.就是将一大段定义样式的代码通过用一个java类的全路径作为标签名就能代替使用。(相当于封装代码)

2.有些效果的控件安卓系统不支持,所以要自己定义,所以有些特殊属性也要自己定义了。

Android自定义组合控件之自定义属性

Android自定义组合控件之自定义属性


步骤一共三步:

1.创建一个类继承View,覆写对应的3个构造方法    如果没有覆写对应的构造方法会出NoSuchMethodException

/**
* 自定义属性:
* 1.创建一个类继承View,覆写对应的3个构造方法 如果没有覆写对应的构造方法会出NoSuchMethodException
* 2.在values目录下创建attrs.xml,并在文件里声明自定义属性集合名称,属性名称和类型
* 3.在布局文件里用自定义类的全路径作为标签名,创建自定义组件
* 1.在命名控件里修改 xmlns:(自定义属性前缀名) com.xxc.attribute表示包名, 其他固定
* xmlns:xxc="http://schemas.android.com/apk/res/com.xxc.attribute"
* 2.在自定义组件中使用自定义属性xxc:test_bitmap="@drawable/ic_launcher"
* 4.在自定义View类里对应的构造函数中,用context.obtainStyledAttributes()解析AttributeSet里的简单加工数据成对象
* 然后就可以获取具体数据了
*
*/
public class MyView extends View {

/**
* 代码创建组件的时候执行
*/
public MyView(Context context) {
super(context);
}


/**
* 在布局文件中创建View对象的时候执行该方法
* @param context 上下文对象
* @param attrs 解析xml对应的自定义组件,简单进行数据处理
*/
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
/*
* 这种方法虽然简便,但是不规范
* @2131034112 因为是引用了别的资源文件里的数据 所以这种方法只返回了id值
*/
System.out.println(attrs.getAttributeValue("http://schemas.android.com/apk/res/com.xxc.attribute","test_msg"));
//hehe
System.out.println(attrs.getAttributeValue(null,"haha"));
/*
* AttributeSet仅对XML的属性进行了简单处理
* name--->layout_width
* value--->-2
* name--->layout_height
* value--->-2
* name--->test_msg
* value--->@2131034112
* name--->test_bitmap
* value--->@2130837504
*/
for (int i = 0; i < attrs.getAttributeCount(); i++) {
String name = attrs.getAttributeName(i);
String value = attrs.getAttributeValue(i);
System.out.println("name--->"+name);
System.out.println("value--->"+value);
}
System.out.println("-------------------------------------------------------------");
//对简单处理后的属性集合进行深加工,返回的TypedArray可以遍历获取具体对象 参数一 AttributeSet 参数二 自定义属性集合名
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);
//这种方法不需要循环
System.out.println("原先方法的id======================="+ta.getString(R.styleable.MyView_test_msg));
int count = ta.getIndexCount();
for (int i = 0; i < count; i++) {
int index = ta.getIndex(i);
switch (index) {
case R.styleable.MyView_test_id:
int id = ta.getInteger(index, -1);
System.out.println("id---->"+id);
break;
case R.styleable.MyView_test_msg:
String msg = ta.getString(index);
System.out.println("msg---->"+msg);
break;
case R.styleable.MyView_test_bitmap:
int resourceId = ta.getResourceId(index, -1);
System.out.println("图片id--->"+resourceId);
break;
}
}

ta.recycle();//释放资源
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

}

2.在values目录下创建attrs.xml,并在文件里声明自定义属性集合名称,属性名称和类型

<?xml version="1.0" encoding="utf-8"?>
<resources>

<!-- 声明属性集的名称 -->
<declare-styleable name="MyView">

<!-- 声明一个属性name是test_id 类型为整数类型 -->
<attr name="test_id" format="integer" />
<!-- 声明一个属性name是test_msg 类型为字符串类型 -->
<attr name="test_msg" format="string" />
<!-- 声明一个属性name是test_bitmap 类型为引用类型 -->
<attr name="test_bitmap" format="reference" />
</declare-styleable>

</resources>

3.在布局文件里用自定义类的全路径作为标签名,创建自定义组件

                         1.在命名控件里修改   xmlns:(自定义属性前缀名)    com.xxc.attribute表示包名  是清单文件里的包名,不是自定义类的包名(千万别搞错),  其他固定

                                  xmlns:xxc="http://schemas.android.com/apk/res/com.xxc.attribute"

                         2.在自定义组件中使用自定义属性xxc:test_bitmap="@drawable/ic_launcher"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xxc="http://schemas.android.com/apk/res/com.xxc.attribute"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.xxc.attribute.MyView
haha="hehe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xxc:test_bitmap="@drawable/ic_launcher"
xxc:test_msg="@string/app_name" />

</RelativeLayout>

4.在自定义View类里对应的构造函数中,用context.obtainStyledAttributes()解析AttributeSet里的简单加工数据成对象  然后就可以获取具体数据了  参照第一步里构造方法里