自定义控件android

来源:互联网 发布:安居客网络经纪人平台 编辑:程序博客网 时间:2024/06/04 18:55

在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>

这样自定义的控件基本就好了。

下面介绍一下,我学习到的自定义控件其他细节(或者说更深的东西吧。。。)

参考下一节的博客,关于自定义开关按键的处理。。

0 0