自定义控件

来源:互联网 发布:数据库表重命名as语句 编辑:程序博客网 时间:2024/06/04 01:03

自定义控件步骤

1、继承自View2、重写构造方法3、重写onMesure(int, int), 测量view的大小4、确定view的位置,view自身有一些建议权,决定权在父view手   中onLayout()5、重写onDraw(canvas)方法

一个自定义开关按钮的Demo

先看效果:

自定义开关

1、构造函数:
    /**     * 在布局文件中声明的view,创建时由系统自动调用     * @param context     * @param attrs     */    public MyToggleButton(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        initView();    }    /**     * 初始化     */    private void initView() {        // TODO Auto-generated method stub        backgroundBitmap =   BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);        slideBtn = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button);        paint = new Paint();        paint.setAntiAlias(true); //抗锯齿        //添加onclick事件监听        setOnClickListener(this);    }
2、重写onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法
@Override    /**     * 测量尺寸时的回调方法     */    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        /**         * 设置当前view的大小         * width : view的宽度         * height : view的高度  单位:像素         */        setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight());    }
3、重写onDraw(Canvas canvas)方法
/**     * 绘制当前view的内容     */    protected void onDraw(Canvas canvas) {        // TODO Auto-generated method stub        //super.onDraw(canvas);        /*         * backgroundBitmap要绘制的图片         * left图片的左边界位置         * top 图片的上边界位置         * paint 绘制图片要使用的画笔         */        canvas.drawBitmap(backgroundBitmap, 0, 0, paint);        canvas.drawBitmap(slideBtn, slide_left, 0, paint);    }
4、响应按钮点击事件
    @Override    public void onClick(View arg0) {        // TODO Auto-generated method stub        /**         * 如果没有拖动,则响应onclick事件         */        if(!isDrag){            curState = !curState;            flushState();        }    }    /**     * 刷新当前状态     */    private void flushState() {        // TODO Auto-generated method stub        if(curState){            slide_left = backgroundBitmap.getWidth() - slideBtn.getWidth();        }else{            slide_left = 0;        }        /*         * 刷新当前view,导致ondraw方法的执行         */        invalidate();    }
完整Demo下载地址:https://github.com/Youjk/MyToggleButton

为控件添加自定义的属性

1、在attrs.xml文件中声明属性,有属性名:name 和 格式:format。如:    <declare-styleable name = "MyToggleBtn">        <attr name = "current_state" format = "boolean">    </declare-styleable>其中format的常用类型有:    reference                引用    color                    颜色    boolean                  布尔值    dimension                尺寸值    float                    浮点值    integer                  整型值    string                   字符串    enum                     布尔值2、在布局文件中使用新属性,使用之前必须先声明命名空间,如:    xmlns:yjk="http://schemas.android.com/apk/res/com.yjk.attars"xmlns:yjk中yjk是命名空间名,com.yjk.attars是自己项目的包名3、在自定义view的构造方法中,通过解析AttributeSet对象,获得所需要的属性值。

下面看个小例子

1、定义MyView继承自view:
package com.yjk.attars;import android.content.Context;import android.content.res.TypedArray;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.View;public class MyView extends View {    public MyView(Context context) {        super(context);        // TODO Auto-generated constructor stub    }    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);}
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_mag 类型是字符串类型 -->        <attr name = "test_msg" format = "string"/>        <!-- 声明一个属性 name是test_bitmap 类型是引用类型 -->        <attr name = "test_bitmap" format = "reference"/>    </declare-styleable></resources>
3、在布局文件中使用属性:
<RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:yjk="http://schemas.android.com/apk/res/com.yjk.attars"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.yjk.attars.MyView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        yjk:test_id = "10"        yjk:test_msg = "sss"        yjk:test_bitmap = "@drawable/ic_launcher"        android:text="@string/hello_world" /></RelativeLayout>
4、在MyView的第二个构造函数中使用这些属性
public MyView(Context context, AttributeSet attrs) {        super(context, attrs);        /*         * AttributeSet 对xml布局进行解析后的结果         * 存储的都是原始数据。仅对数据进行简单加工         */        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);        }        System.out.println("----------");        /*         * TypeArray 是对AttributeSet中的原始数据 按照图纸中的说明(R.styleable.MyView 中的类型声明)         * 创建出具体的对象          */         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView);         int taCount = a.getIndexCount();         for(int i = 0; i < taCount; ++i){             int index = a.getIndex(i);             System.out.println(index);             switch(index){             case R.styleable.MyView_test_id:                 a.getInt(index, 5);                 break;             case R.styleable.MyView_test_msg:                 a.getString(index);                 break;             case R.styleable.MyView_test_bitmap:                 a.getDrawable(index);                 break;             }         }    }
打印内容:

这里写图片描述

可以看出使用TypeArray更方便
0 0
原创粉丝点击