1.先看他在页面布局中的使用,这是布局中的一段
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myattrs="http://schemas.android.com/apk/res/cn.zectec.ptt"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eee"
android:orientation="vertical" >
。。。。。。。
<LinearLayout
android:id="@+id/ll_group_scan"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:background="#fff"
android:gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
style="@style/setting_image_style"
android:layout_marginLeft="20dp"
android:background="@drawable/group_scan" />
<TextView
style="@style/setting_text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="@string/group_scan" />
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<cn.zectec.ptt.view.MToggleButton
android:id="@+id/btn_mtogglebutton"
android:layout_width="80dp"
android:layout_height="30dp"
android:layout_marginRight="20dp"
myattrs:mtogglebutton_background_off="@drawable/mtogglebutton_background_off"
myattrs:mtogglebutton_background_on="@drawable/mtogglebutton_background_on"
myattrs:mtogglebutton_button="@drawable/mtogglebutton_button" />
</LinearLayout>
。。。。。。
</LinearLayout>
mtogglebutton_background_off:<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 填充颜色 -->
<solid android:color="#cccccc" />
<!-- 矩形的圆角半径 -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<!-- 线的宽度,颜色灰色 -->
<stroke
android:width="1dp"
android:color="#FFFFFF" >
</stroke>
<size
android:width="80dp"
android:height="30dp"/>
</shape>
mtogglebutton_background_on:<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 填充颜色 -->
<solid android:color="#43D7A3" />
<!-- 矩形的圆角半径 -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<!-- 线的宽度,颜色灰色 -->
<stroke
android:width="1dp"
android:color="#FFFFFF" >
</stroke>
<size
android:width="80dp"
android:height="30dp"/>
</shape>
3.自定义开关的类:
public class MToggleButton extends View {
private Bitmap sildBtn;
private Paint paint;
private boolean currState;
private Context context;
public MToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
// 根据属性集合和上下文 来设置id
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MToggleBtn);
Drawable drawable = ta.getDrawable(R.styleable.MToggleBtn_mtogglebutton_background_on);
Bitmap bitmap = BitmapUtil.drawableToBitmap(drawable);
bitmap_bg_on = Bitmap.createScaledBitmap(bitmap,DensityUtil.dip2px(context, 80), DensityUtil.dip2px(context, 26), true);
Drawable drawable3 = ta.getDrawable(R.styleable.MToggleBtn_mtogglebutton_background_off);
Bitmap bitmap3 = BitmapUtil.drawableToBitmap(drawable3);
bitmap_bg_off = Bitmap.createScaledBitmap(bitmap3,DensityUtil.dip2px(context, 80), DensityUtil.dip2px(context, 26), true);
Drawable drawable2=ta.getDrawable(R.styleable.MToggleBtn_mtogglebutton_button);
Bitmap bitmap2 = BitmapUtil.drawableToBitmap(drawable2);
sildBtn = Bitmap.createScaledBitmap(bitmap2, DensityUtil.dip2px(context, 38), DensityUtil.dip2px(context, 22), true);
initView();
}
public MToggleButton(Context context) {
super(context);
this.context = context;
initView();
}
@SuppressWarnings("deprecation")
private void initView() {
// bitmap_bg = BitmapFactory.decodeResource(getResources(),
// R.drawable.mtogglebutton_background_off);
// sildBtn = BitmapFactory.decodeResource(getResources(),
// R.drawable.mtogglebutton_button);
// Drawable drawable = getResources().getDrawable(R.drawable.mtogglebutton_background);
// Bitmap bitmap = BitmapUtil.drawableToBitmap(drawable);
// bitmap_bg = Bitmap.createScaledBitmap(bitmap,DensityUtil.dip2px(context, 80), DensityUtil.dip2px(context, 30), true);
//
// Drawable drawable2 = getResources().getDrawable(R.drawable.mtogglebutton_button);
// Bitmap bitmap2 = BitmapUtil.drawableToBitmap(drawable);
// sildBtn = Bitmap.createScaledBitmap(bitmap2, DensityUtil.dip2px(context, 40), DensityUtil.dip2px(context, 30), true);
sildBtnLeftMax = bitmap_bg_on.getWidth() - sildBtn.getWidth() - DensityUtil.dip2px(context, 4);
paint = new Paint();
paint.setAntiAlias(true);
// 添加按钮的监听事件
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 如果是滑动,不执行点击
if (isDrop) {
return;
}
// 点击时切换按钮的状态,声明一个布尔的变量
currState = !currState;
// 设置按钮状态的监听
if (onBtnClickListener != null) {
onBtnClickListener.onBtnClick(currState);
}
// 刷新状态
flushState();
}
});
}
// 添加滑动事件,这里需要重写onTouchEvent(MotionEvent event)
/**
* 判断是否发生拖动,我们定义:如果按下,移动在15像素之内,抬起,我们认为是点击,按点击的逻辑处理开关 如果,按下并移动超过15
* 个像素,我们认为是拖动,按拖动的逻辑处理开关
*/
private int startx;
private int endx;
private boolean isDrop;
@Override
public boolean onTouchEvent(MotionEvent event) {
/**
* 点击事件,也是触摸事件的一种,当发生UP事件时,
* 系统就认为发生了点击的动作,就会执行,onclickListener.onClick(View) 方法
* 但系统对点击事件的解析很粗糙,只要发生UP事件,就认为发生了点击的动作
*/
super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startx = (int) event.getRawX();
isDrop = false;
break;
case MotionEvent.ACTION_MOVE:
endx = (int) event.getRawX();
int disx = endx - startx;
sildBtnLeft += disx;
// 刷新view
flushView();
startx = endx;
// 当移动距离大于15时,设为true
if (Math.abs(disx) > 15) {
isDrop = true;
}
break;
case MotionEvent.ACTION_UP:
if (isDrop) {
if (sildBtnLeft > sildBtnLeftMax / 2) {
currState = true;
} else {
currState = false;
}
flushState();
}
break;
default:
break;
}
return true;
}
public void flushState() {
if (currState) {
sildBtnLeft = sildBtnLeftMax;
} else {
sildBtnLeft = 0;
}
// 刷新view
flushView();
}
private void flushView() {
// 先对sildBtnLeft的值进行判断
if (sildBtnLeft < 0) {
sildBtnLeft = 0;
} else if (sildBtnLeft > sildBtnLeftMax) {
sildBtnLeft = sildBtnLeftMax;
}
// 通知系统 ,刷新页面,会导致 onDraw 方法的执行
invalidate();
}
/**
* 一个view从创建到显示到屏幕上,要经历的步骤 一、测量控件的大小 onMeasure(int widthMeasureSpec, int
* heightMeasureSpec); 二、指定位置。 onLayout(boolean changed, int left, int top,
* int right,int bottom); 三、绘制控件 onDraw(Canvas canvas);
*
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = bitmap_bg_on.getWidth();
int height = bitmap_bg_on.getHeight();
// 设置背景图片与控件的大小相同
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
// TODO Auto-generated method stub
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制背景
/**
* 参数二,是图片在左边距, 参数三,是图片在上边距,
*/
if (currState) {
canvas.drawBitmap(bitmap_bg_on, 0, 0, paint);
}else {
canvas.drawBitmap(bitmap_bg_off, 0, 0, paint);
}
// 绘制按钮
canvas.drawBitmap(sildBtn, sildBtnLeft+DensityUtil.dip2px(context, 2), DensityUtil.dip2px(context, 2), paint);
}
// 定义按钮距离左边的距离
private float sildBtnLeft = 0;
private int sildBtnLeftMax;
private Bitmap bitmap_bg_on;
private Bitmap bitmap_bg_off;
// 开关的监听
private OnBtnClickListener onBtnClickListener;
public void setOnBtnClick(OnBtnClickListener onBtnClickListener) {
this.onBtnClickListener = onBtnClickListener;
}
public interface OnBtnClickListener {
void onBtnClick(boolean currState);
}
public void initToggleState(boolean isOpenGroupScan) {
if (isOpenGroupScan) {
currState = true;
sildBtnLeft = sildBtnLeftMax;
} else {
currState = false;
sildBtnLeft = 0;
}
// 刷新view
flushView();
}
}
这里,自定义的开关可拖动也可点击,里面有个px和dp的转换工具类,以及图片的转换工具类,请参考我的以前博客。
4.页面中的使用
mToggleButton.initToggleState(false);//初始化开关状态
//为开关设置点击事件监听
<pre name="code" class="java">mToggleButton.setOnBtnClick(new OnBtnClickListenerImplementation());
private final class OnBtnClickListenerImplementation implements
OnBtnClickListener{
@Override
public void onBtnClick(boolean currState) {//点击开关按钮
<span style="white-space:pre"> </span>//开启或关闭。。。。
}
}