自定义控件:用户根据自己需求,自己定制的控件。
方式: 继承已有控件、继承view、 继承viewGroup
1.继承view,定制单一控件
2.继承ViewGroup,定制控件组
例: 自定义滑动开关
1. 继续View , 在构造方法中初始化图片资源,图片资源放在drawable目录下
2. 实现onMeasure方法,用来测量控件的宽和高
3. 实现onDraw方法, 把控件画出来。
4. 实现onTouchEvent方法,实现控件的滑动,并改变状态 ,调用invalidate重新绘制控件
5. 定义接口,在onTouchEvent方法, MotionEvent.ACTION_UP时判断状态,并实现事件回调
1.
public SlideButton(Context context, AttributeSet attrs) {
super(context, attrs);
initBitmap();
}
/**
* 初始化图片
*/
private void initBitmap() {
slideButtonBG = BitmapFactory.decodeResource(getResources(),
R.drawable.slide_button_background);
switchBG = BitmapFactory.decodeResource(getResources(),
R.drawable.switch_background);
}
2.
/**
* 测量当前开关的宽高时回调
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 设置开关的宽高
setMeasuredDimension(switchBG.getWidth(), switchBG.getHeight());
}
3.
/**
* 绘制当前控件的方法
*/
@Override
protected void onDraw(Canvas canvas) {
// 1.把滑动开关的背景画到画布上
canvas.drawBitmap(switchBG, 0, 0, null);
// 2. 绘制滑动块显示的位置 ,开或关
if(isSliding) {
int left = currentX - (slideButtonBG.getWidth()/2);
if(left < 0) {
left = 0;
} else if(left > switchBG.getWidth() - slideButtonBG.getWidth()) {
left = switchBG.getWidth() - slideButtonBG.getWidth();
}
canvas.drawBitmap(slideButtonBG, left, 0, null);
} else {
if (currentState) { // 绘制开关为开的状态
canvas.drawBitmap(slideButtonBG, switchBG.getWidth()
- slideButtonBG.getWidth(), 0, null);
} else { // 绘制开关为关的状态
canvas.drawBitmap(slideButtonBG, 0, 0, null);
}
}
super.onDraw(canvas);
}
4.
/**
* 当产生触摸事件时回调的方法
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
currentX = (int) event.getX();
isSliding = true;
break;
case MotionEvent.ACTION_MOVE:
currentX = (int) event.getX();
break;
case MotionEvent.ACTION_UP:
isSliding = false ;
//判断当前滑动块,偏向于哪一边, 如果滑动块的中心点小于背景的中心点,设置为关闭状态 ,
int bgCenter = switchBG.getWidth() / 2 ;
boolean state = currentX > bgCenter;
//调用用户的监听 事件
if(state != currentState && mListener != null) {
mListener.onToggleStateChanged(state);
}
currentState = state;
break;
}
invalidate(); //刷新当前控件 ,会引起onDraw方法的调用
return true;
}