自定义控件
来源:互联网 发布:数据库表重命名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
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 自定义控件
- 编写一个函数根据人的年龄及逆行排序存储
- LDAP概念
- windows mobile 6.5 百度输入法 如何集成到系统中去
- 图像深度
- Ubuntu搭建LAMP及相关配置
- 自定义控件
- 编辑距离及其回溯路径
- 内存分配与处理函数
- 初识软考之Java环境配置
- MQTT协议简记
- jquery datatable 参数
- JVM内存结构解析(一)
- 如何简单地在浏览器中使用阿里云的文件上传功能?
- Android 权限配置