5.自定义开关:ToggleView小案例
2019-06-30 本文已影响0人
BusyBunny
自定义开关:
-
1.案例演示:
ToggleView.gif -
2.实现逻辑:
- 1.编写MyToggleView继承View;
- 2.自定义属性,通过Bitmap加载资源(SwitchBackground、SlideButton和开关状态)
//自定义属性:
//1.先在value/attrs.xml编写;
<resources>
<declare-styleable name="TogglesView">
<attr name="switch_background" format="reference"></attr>
<attr name="slide_button" format="reference"></attr>
<attr name="state" format="boolean"></attr>
</declare-styleable>
</resources>
//2.在布局xml文件进行设置:
<com.bunny.widgetdemo.ToggleDemo.MyToggleView
android:id="@+id/toggle_view"
app:slide_button="@drawable/slide_button"
app:switch_background="@drawable/switch_background"
app:state="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
//3.在自定义的控件中进行使用:
private void initAttrs(AttributeSet attrs) {
String NAMESPACE="http://schemas.android.com/apk/res-auto";
//设置滑动按钮图片:
int slide_button = attrs.getAttributeResourceValue(NAMESPACE, "slide_button", -1);
//设置滑动的背景:
int switch_background = attrs.getAttributeResourceValue(NAMESPACE, "switch_background", -1);
//设置默认滑动状态:
slideState = attrs.getAttributeBooleanValue(NAMESPACE, "state", false);
//5.资源设置
setSlideButton(slide_button);
setSwitchBackground(switch_background);
setState(slideState);
}
//获取SlideButton
public void setSlideButton(int slide_button) {
slideButtonBitmap = BitmapFactory.decodeResource(getResources(),slide_button);
}
//获取SwitchBackground
public void setSwitchBackground(int switch_background) {
switchBackgroundBitmap=BitmapFactory.decodeResource(getResources(),switch_background);
}
//设置状态值
public void setState(boolean isSlideState) {
slideState=isSlideState;
}
- 3.将该控件的宽高设置为SwitchBackground的宽高,故重写onMeasure()方法;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(switchBackgroundBitmap.getWidth(),switchBackgroundBitmap.getHeight());
}
- 4.重写onDraw()方法,绘制SwitchBackground和SlideButton;
@Override
protected void onDraw(Canvas canvas) {
//绘制switchBackgroundBitmap
canvas.drawBitmap(switchBackgroundBitmap,0,0,mPaint);
if (isTouch){//判断是否触摸着:
//设置滑块的偏移位置:让滑块偏移自身位置的一半,使得滑块恰好刚刚移动到合适位置
float newLeft=mTouchX-slideButtonBitmap.getWidth()/2.0f;
//限定边界:
if (newLeft<0) newLeft=0;
if (newLeft>switchBackgroundBitmap.getWidth()-slideButtonBitmap.getWidth()) newLeft=switchBackgroundBitmap.getWidth()-slideButtonBitmap.getWidth();
//绘制移动的slideButton
canvas.drawBitmap(slideButtonBitmap,newLeft,0,mPaint);
}else{
//未触摸:
if (slideState){
//默认为关
canvas.drawBitmap(slideButtonBitmap,0,0,mPaint);
}else{
//开的状态
canvas.drawBitmap(slideButtonBitmap,switchBackgroundBitmap.getWidth()-slideButtonBitmap.getWidth(),0,mPaint);
}
}
}
- 5.回调,将开关状态向外部暴露;
//1.编写一个监听者接口,并向外暴露状态:
public interface onSwitchStateUpdateListener{
//向外部暴露状态:
void onStateUpdate(boolean state);
}
//2.添加接口对象,以便于外部调用
public void setOnSwitchStateUpdateListener(onSwitchStateUpdateListener onSwitchStateUpdateListener){
this.onSwitchStateUpdateListener=onSwitchStateUpdateListener;
}
//3.在合适的位置进行调用方法:
onSwitchStateUpdateListener.onStateUpdate(slideState);
//4.外部实现:
toggleView.setOnSwitchStateUpdateListener(new ToggleView.onSwitchStateUpdateListener() {
@Override
public void onStateUpdate(boolean state) {
Toast.makeText(ToggleActivity.this, "状态:"+state, Toast.LENGTH_SHORT).show();
}
});