自定义控件android

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值