在android的使用过程中,很多时候,系统自带的控件不能满足要求的时候,都要使用自己的控件,今天,分享一下,我学习过的自定义控件。
1,要在values中创建一个attrs.xml文件
2,在文件中写号你要自定义控件的属性。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--声明属性集的名称-->
<declare-styleable name="MyView">
<!--声明一个属性为 name是test_id,类型为整数类型-->
<attr name="test_id" format="integer" />
<!--类型为字符串-->
<attr name="test_msg" format="string"/>
<!--类型为 引用资源类型-->
<attr name="test_bitmap" format="reference" />
</declare-styleable>
</resources>
3,在java文件中创建自定义的java文件,
比如,本文中的在
com.sdingba.su.androidstart20.MyView路径下的文件。
一般重新2个够着方法,如果在xml布局文件中使用的话,系统默认调用有2个参数的构造函数的方法,所以,一定要重写2个参数的构造方法。
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
/**
* AttributeSet 对xml文件解析后的结果,封装成attributeset
* 存储的都是原始数据,仅对数据进行简单的加工
*/
int count = attrs.getAttributeCount();
for (int i = 0; i < count; i++) {
String name = attrs.getAttributeName(i);
String value = attrs.getAttributeValue(i);
// System.out.println(name + "<<<" + value);
}
/**
* 对AttributeSet中的原始数据按照图纸中的说明(
* R.styleable.MyView)
* 创建出具体的对象。
*/
//Container for an array of values that were retrieved with
TypedArray ta = context.obtainStyledAttributes(
attrs, R.styleable.MyView);
/*获得对象的个数,*/
int x = ta.getIndexCount();
System.out.println("=======================");
for (int i = 0; i < x; i++) {
int index = ta.getIndex(i);
System.out.println(index);
int bitmap = ta.getResourceId(index, 100);
switch (index) {
case R.styleable.MyView_test_bitmap:
ta.getDrawable(index);
System.out.println("bitmap:::"+bitmap);
break;
case R.styleable.MyView_test_id:
ta.getInt(index, 10);
break;
case R.styleable.MyView_test_msg:
String a = ta.getString(index);
System.out.println(" msg "+a);
break;
}
}
}
}
4,在xml布局文件中使用该类的方法,
<!--文件的路径名-->
<com.sdingba.su.androidstart20.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
sdingba:test_msg="自定义属性28"
sdingba:test_bitmap="@mipmap/ic_launcher"
android:textSize="16dp" />
5,在4步骤中的xml布局文件声明android的命名空间。
注解: xmlns:sdingba=”http://schemas.android.com/apk/res/都是一样的,要添加文件的路劲,然后修改文件的命名空间的名字
本文使用的命名空间名称叫sdingba
xmlns:sdingba="http://schemas.android.com/apk/res/com.sdingba.su.androidstart20"
步骤2中的TypedArray的解析方法,主要是获取自定义控件的属性,。
//获得自定义的属性
TypedArray ta = context.obtainStyledAttributes(
attrs, R.styleable.MyToggleBtn);
但是还可以通过下面的方法来获取自定义控件的属性。
第一个引号:文件命名空间的路径,
第二个引号:自定义控件的名称。
String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.sdingba.mobilesafe", "title");
desc_on = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.sdingba.mobilesafe", "desc_on");
desc_off = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.sdingba.mobilesafe", "desc_off");
6,可以给自定义的java类添加 属性。比如下面的。
public class SettingClickView extends RelativeLayout {
private TextView tv_desc;
private TextView tv_title;
private String desc_on;
private String desc_off;
/**
* 初始化布局文件
* @param context
*/
private void iniView(Context context) {
//把一个布局文件---》View 并且加载在SettingItemView
View.inflate(context, R.layout.setting_click_view, this);
tv_desc = (TextView) this.findViewById(R.id.tv_desc);
tv_title = (TextView) this.findViewById(R.id.tv_title);
}
public SettingClickView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
iniView(context);
}
/**这里写代码片
* 带有两个参数的构造方法,布局文件使用的时候调用
* @param context
* @param attrs
*/
public SettingClickView(Context context, AttributeSet attrs) {
super(context, attrs);
iniView(context);
String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.sdingba.mobilesafe", "title");
desc_on = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.sdingba.mobilesafe", "desc_on");
desc_off = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.sdingba.mobilesafe", "desc_off");
tv_title.setText(title);
setDesc(desc_off);
}
public SettingClickView(Context context) {
super(context);
iniView(context);
}
/**
* 设置组合控件的状态
*/
public void setChecked(boolean checked){
if(checked){
setDesc(desc_on);
}else{
setDesc(desc_off);
}
}
/**
* 设置 组合控件的描述信息
*/
public void setDesc(String text){
tv_desc.setText(text);
}
/**
* 设置组合控件的标题
*/
public void setTitle(String title){
tv_title.setText(title);
}
}
//对应的xml文件如下:
<com.sdingba.mobilesafe.ui.SettingItemView
android:id="@+id/siv_show_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
itheima:desc_off="设置显示号码归属地已经关闭"
itheima:desc_on="设置显示号码归属地已经开启"
itheima:title="设置显示号码归属地" >
</com.sdingba.mobilesafe.ui.SettingItemView>
这样自定义的控件基本就好了。
下面介绍一下,我学习到的自定义控件其他细节(或者说更深的东西吧。。。)
参考下一节的博客,关于自定义开关按键的处理。。