滑动开关的实现
分析:根据效果图分析,需要如下属性,背景图,滑块图
1.这是一个自定义view
2.无需布局(因为提供了背景图和滑块图,只需要绘制)
3.根据开关的状态,来绘制滑块的位置
*首先分析属性,在attr文件中配置
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="backgroundImg" format="reference"></attr>
<attr name="switchImg" format="reference"></attr>
<declare-styleable name="CutomSwitchToggle">
<attr name="backgroundImg"></attr>
<attr name="switchImg"></attr>
</declare-styleable>
</resources>
*自定义view代码获取属性
package com.andriodbus.switchtoggle;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/*
* @项目名: SwitchToggle
* @包名:com.andriodbus.switchtoggle
* @文件名: SwitchToggleView
* @创建者: Administrator
* @创建时间: 2016/8/21 0021 下午 8:00
* @描述:TODO
*/
public class SwitchToggleView extends View {
/**
* 开关的关闭状态
*/
public boolean isClose = false;
/**
* 背景图
* @param context
*/
private Bitmap mBgImage;
/**
* 滑块图
* @param context
*/
private Bitmap mSwitchImage;
private Paint mPaint;
private int mWidth;
private int mHeight;
private OnToggleClickListenter listenter;
public SwitchToggleView(Context context) {
this(context, null);
}
public SwitchToggleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwitchToggleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取属性
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.CutomSwitchToggle,
defStyleAttr,
0);
//获取属性个数
int indexCount = ta.getIndexCount();
//遍历属性
for (int i = 0; i < indexCount; i++) {
int index = ta.getIndex(i);
switch (index) {
//背景图
case R.styleable.CutomSwitchToggle_backgroundImg:
mBgImage = BitmapFactory.decodeResource(getResources(),
ta.getResourceId(index,
R.drawable.switch_background));
break;
//滑块图
case R.styleable.CutomSwitchToggle_switchImg:
mSwitchImage = BitmapFactory.decodeResource(getResources(),
ta.getResourceId(index,
R.drawable.switch_button));
break;
}
}
ta.recycle();
mPaint = new Paint();
//当自定义开关点击时,改变开关状态
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
isClose = !isClose;
//触发重新绘制
postInvalidate();
if (listenter != null) {
listenter.OnToggleClick(isClose);
}
}
});
}
/**
* 绘制
*/
@Override
protected void onDraw(Canvas canvas) {
//绘制背景
canvas.drawBitmap(mBgImage, 0, 0, mPaint);
//根据开关的关闭状态绘制开关位置
if (isClose) {
canvas.drawBitmap(mSwitchImage, 0, 0, mPaint);
} else {
canvas.drawBitmap(mSwitchImage,
mBgImage.getWidth() - mSwitchImage.getWidth(),
0,
mPaint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取父容器建议的宽高大小和模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
mWidth = 0;
mHeight = 0;
//测量背景
int bgWidth = mBgImage.getWidth();
int bgHeight = mBgImage.getHeight();
if (widthMode == MeasureSpec.EXACTLY) { //EXACTLY | match_parent 模式
mWidth = widthSize;
} else {
//由背景图决定的宽
int desireWidthByImage = getPaddingLeft() + bgWidth + getPaddingRight();
if (widthMode == MeasureSpec.AT_MOST) { //AT_MOST | wrap_content模式
mWidth = Math.min(widthSize, desireWidthByImage);
}
}
if (heightMode == MeasureSpec.EXACTLY) { //EXACTLY | match_parent 模式
mHeight = heightSize;
} else {
//由背景图决定的高
int desireHeightByImage = getPaddingTop() + bgHeight + getPaddingBottom();
if (heightMode == MeasureSpec.AT_MOST) { //AT_MOST | wrap_content模式
mHeight = Math.min(heightSize, desireHeightByImage);
}
}
//将最终测量计算结果返回
setMeasuredDimension(mWidth, mHeight);
}
public void setOnToggleClickListenter(OnToggleClickListenter listenter) {
this.listenter = listenter;
}
/**
* 给开关设置点击事件,回调出去
*/
public interface OnToggleClickListenter {
void OnToggleClick(boolean isClose);
}
}
*activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.itheima.andriodbus.switchtoggle.MainActivity">
<com.andriodbus.switchtoggle.SwitchToggleView
android:id="@+id/stv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundImg="@drawable/switch_background"
app:switchImg="@drawable/switch_button">
</com.andriodbus.switchtoggle.SwitchToggleView>
</RelativeLayout>
*