Android-自定义控件
一、概述
有时候Android UI要用到自己设计的控件样式时,需要自己动手定义一个UI控件,这类控件就是自定义控件。
二、步骤
1、写一个类继承View
(1)创建3个构造方法,对其中多参数的进行讲解:
public MySwitchView(Context context, AttributeSet attrs, int defStyleAttr)
参数context:上下文对象
参数attrs:属性集,可以接收布局xml中对该View的属性设置。
参数defStyleAttr:
(2)重写onDraw,进行绘制
<1>方法介绍:
@Override
protected void onDraw(Canvas canvas)
参数 canvas:画布对象。
<2>使用示例:
@Override
protected void onDraw(Canvas canvas) {
// 绘制200x200的矩形
// canvas.drawRect(0, 0, 200, 200, mPaint);
// 绘制背景图片
canvas.drawBitmap(Bitmap对象类型, x轴坐标, y轴坐标, null);
}
(3)重写onMeasure,修改尺寸
<1>方法介绍:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
参数widthMeasureSpec:宽
参数heightMeasureSpec:高
<2>使用示例:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// setMeasuredDimension(100, 100);// 将当前控件宽高设置为100x100
//依据背景图片来确定控件大小
setMeasuredDimension(mBitmapBg.getWidth(), mBitmapBg.getHeight());
}
(4)设置监听器,供调用者使用。
private OnCheckChangeListener mListener;
// 设置开关状态监听
public void setOnCheckChangeListener(OnCheckChangeListener listener) {
mListener = listener;
}
//监听开关状态的回调接口
public interface OnCheckChangeListener {
public void onCheckChanged(View view, boolean isChecked);
}
注意:onCheckChanged的方法体在调用者里面自己定义,但是调用这个方法的时机却是在这个继承View的类中。
2、在xml布局文件中配置
(1)在res/values文件夹创建attrs.xml文件来设置属性:
<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MySwitchView">
<attr name="slide" format="reference" />
<attr name="checked" format="boolean" />
</declare-styleable>
</resources></span>
注意:第3行代码 <declare-styleable name="MySwitchView">的name要和继承View的类同名。
(2)使用时需要指定包名:如eclipse中:
<span style="font-size:18px;"><RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myswitch="http://schemas.android.com/apk/res/com.sqb.as_it1"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<span style="white-space:pre"> </span><com.sqb.myswitch.MySwitchView
android:id="@+id/ms_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
myswitch:checked="true"
myswitch:slide="@drawable/slide_button" />
</RelativeLayout></span>
注意:
第3行代码,在eclipse里面的用法如下:
xmlns:myswitch="http://schemas.android.com/apk/res/com.sqb.as_it1"
表示xml的namespace为myswitch,值等于“http://schem……b.as_it1”
第3行代码,在Android studio里面的用法如下:
xmlns:myswitch="http://schemas.android.com/apk/res-auto"
注意:
最后两行: myswitch:checked="true"
myswitch:slide="@drawable/slide_button"
表示自定义的View的属性,会传送给继承View的类的构造方法里面的AttributeSet 参数里面,然后自己对这些属性进行处理。
(2)属性的获取。
<1>需要在继承View的类里面定义一个命名空间,此命名空间的字符串要和布局中指定的一致,如:
private static final String NAMESPACE = "http://schemas.android.com/apk/res/com.sqb.as_it1";
<2>在Android studio中命名空间的字符串也要和xml的一样,即:
private static final String NAMESPACE = "http://schemas.android.com/apk/res-auto";
<3>在构造方法里面获取xml的属性,如:
// 获取属性值
isOpen = attrs.getAttributeBooleanValue(NAMESPACE, "checked", false);
// 加载自定义滑块图片
int slideId = attrs.getAttributeResourceValue(NAMESPACE, "slide", -1);
3、在Activity类中使用
(1)和普通的View一样获取id,如:
mSwitchView = (MySwitchView) findViewById(R.id.ms_switch);
(2)设置监听器,如:
mSwitch.setOnCheckChangeListener(new OnCheckChangeListener() {
@Override
public void onCheckChanged(View view, boolean isChecked) {
Toast.makeText(getApplicationContext(), "当前状态:" + isChecked,
Toast.LENGTH_SHORT).show();
}
});
三、注意事项
1、需要注意如下文件是否正确配置有:
(1)自定义继承View的类文件
(2)res/values/attrs.xml文件
(3)使用时的xml布局文件