【Android工程师】自定义控件 - ToggleView(开关状态选择器)

本文介绍了如何实现一个自定义的ToggleView控件,它作为一个开关状态选择器,支持根据用户点击和滑动切换状态。ToggleView的主要功能包括跟踪用户操作和更新开关状态,并提供了设置背景图片、滑动按钮图片资源以及状态改变监听的方法。

ToggleView是一个开关状态选择器

GitHub:https://github.com/zerolhp/ToggleView


主要功能

1、能够根据点击来进行切换开关

2、能够跟踪用户手指操作来移动开关,并判断用户抬起处对应的开关状态。

开发流程(这里只介绍ToggleView类的开发,完整代码请参考:https://github.com/zerolhp/ToggleView)

1、创建ToggleView类继承View

public class ToggleView extends View

2、在构造函数中创建init()方法 - 做一些必要的初始化工作,如:创建画笔、加载View等。

/** 必须重写该构造函数 */
public ToggleView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}


private void init() {
paint = new Paint();
}

3、重写onMeasure()方法 - 做一些必要的测绘工作

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);


setMeasuredDimension(switchBackgroundBitmap.getWidth(), switchBackgroundBitmap.getHeight());
widthMinus = switchBackgroundBitmap.getWidth() - slideButtonBitmap.getWidth();
center = switchBackgroundBitmap.getWidth() / 2.0f;
}

4、重写onDraw() - 绘图

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);


// 绘制背景
canvas.drawBitmap(switchBackgroundBitmap, 0, 0, paint);
// 根据开关状态决定按钮的显示位置
if (isMove) {
if (curX >= (widthMinus + slideButtonBitmap.getWidth() / 2.0f)) {
curX = widthMinus + slideButtonBitmap.getWidth() / 2.0f;
}
if (curX <= slideButtonBitmap.getWidth() / 2.0f) {
curX = slideButtonBitmap.getWidth() / 2.0f;
}
canvas.drawBitmap(slideButtonBitmap, curX - slideButtonBitmap.getWidth() / 2.0f, 0, paint);
} else {
if (isSwitchOn) {
canvas.drawBitmap(slideButtonBitmap, 0, 0, paint);
} else {
canvas.drawBitmap(slideButtonBitmap, // 要显示的位图
switchBackgroundBitmap.getWidth() - slideButtonBitmap.getWidth(), // 起始点的X坐标
0, // 起始点的Y坐标
paint); // 画笔
}
}
}

5、重写onTouchEvent() - 监听用户操作

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
isMove = true;
curX = event.getX(); // 不是整个屏幕的X坐标,而是本View的X坐标。
break;
case MotionEvent.ACTION_DOWN:


break;
case MotionEvent.ACTION_UP:
// 抬起时不再是isMove状态
isMove = false;
// 判断点击为位置对应哪种状态
boolean state = (event.getX() < center);
// 如果抬起的位置对应的开关状态与原开关状态不同,则
// 注:如果调用者没有设置监听,那么监听接口对象为null,此处不加判断会空指针。
if (state != isSwitchOn && onSwitchStateChangedListener != null) {
// 更新开关状态,以实现监听,并返回给调用者。
onSwitchStateChangedListener.onStateChanged(state);
}
// 更新开关状态
isSwitchOn = state;
break;


default:
break;
}
invalidate(); // 重绘View
return true; // 消费该事件
}

6、创建常用的业务方法

/** 设置背景图片 */
public void setSwitchBackgroundResource(int switchBackgroundId) {
switchBackgroundBitmap = BitmapFactory.decodeResource(getResources(), switchBackgroundId);
}


/** 设置滑动按钮图片资源 */
public void setSlideButtonResource(int slideButtonId) {
slideButtonBitmap = BitmapFactory.decodeResource(getResources(), slideButtonId);
}


/** 设置开关状态 */
public void setSwitchState(boolean isSwitchOn) {
this.isSwitchOn = isSwitchOn;
}

7、创建回调接口和其对应的业务方法

/** 提供方法:设置监听  */
public void setOnSwitchStateChangedListener(OnSwitchStateChangedListener onSwitchStateChangedListener) {
// 传入监听接口对象
this.onSwitchStateChangedListener = onSwitchStateChangedListener;
}

/** 提供回调接口:监听状态接口  */
public interface OnSwitchStateChangedListener {
// 状态回调方法:监听本View的开关状态并传递给调用者使用
void onStateChanged(boolean state);
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值