您的位置:首页 > 移动开发 > Android开发

android仿ios开关按钮

2016-09-21 17:45 417 查看
效果图



实现起来比较简单,直接上代码。

package com.chm.web.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.chm.web.R;

/**
* Created by charmingfst on 2016/9/20.
*/
public class SlipButton extends View
{
private boolean nowChoose = false;// 记录当前按钮是否打开,true为打开,flase为关闭

private boolean onSlip = false;// 记录是否在滑动

private float nowX;// 当前的x

private OnChangedListener changeListener;

private Bitmap bg_on, bg_off, slip_btn;

public SlipButton(Context context)
{
super(context);
init();
}

public SlipButton(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}

public SlipButton(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init();
}

private void init()
{// 初始化

bg_on = BitmapFactory.decodeResource(getResources(), R.drawable.split_left_1);
bg_off = BitmapFactory.decodeResource(getResources(), R.drawable.split_right_1);
slip_btn = BitmapFactory.decodeResource(getResources(), R.drawable.dian);
//        Btn_On = new Rect(0, 0, slip_btn.getWidth(), slip_btn.getHeight());
//        Btn_Off = new Rect(bg_off.getWidth() - slip_btn.getWidth(), 0, bg_off.getWidth(),
//                slip_btn.getHeight());

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        setMeasuredDimension(bg_off.getWidth(), bg_off.getHeight());
int width = measureDimension(bg_off.getWidth(), widthMeasureSpec);
int height = measureDimension(bg_off.getHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}

public int measureDimension(int expriedSize, int measureSpec){
int result;

int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

if(specMode == MeasureSpec.EXACTLY){
result = specSize;
}else{
result = expriedSize;   //UNSPECIFIED
if(specMode == MeasureSpec.AT_MOST){
result = Math.min(result, specSize);
}
}
return result;
}
@Override
protected void onDraw(Canvas canvas)
{

super.onDraw(canvas);

Matrix matrix = new Matrix();
Paint paint = new Paint();
float x; //滑动点到左边的距离

if (onSlip)// 是否是在滑动状态,

{
if (nowX < (bg_on.getWidth() / 2))// 滑动到前半段与后半段的背景不同,在此做判断
{
canvas.drawBitmap(bg_off, matrix, paint);// 画出关闭时的背景
}
else
{
canvas.drawBitmap(bg_on, matrix, paint);// 画出打开时的背景
}

//计算游标距离
if (nowX >= bg_on.getWidth())// 是否划出指定范围,不能让游标跑到外头,必须做这个判断

x = bg_on.getWidth() - slip_btn.getWidth() / 2;// 减去游标1/2的长度...

else if (nowX < 0)
{
x = 0;
}
else
{
x = nowX - slip_btn.getWidth() / 2;
}

}
else
{// 非滑动状态

if (nowChoose)// 根据现在的开关状态设置画游标的位置
{
x = bg_off.getWidth() - slip_btn.getWidth();
canvas.drawBitmap(bg_on, matrix, paint);// 初始状态为true时应该画出打开状态图片
}
else
{
x = 0;
canvas.drawBitmap(bg_off, matrix, paint);
}
}

if (x < 0)// 对游标位置进行异常判断...
x = 0;
else if (x > bg_on.getWidth() - slip_btn.getWidth())
x = bg_on.getWidth() - slip_btn.getWidth();
canvas.drawBitmap(slip_btn, x, 0, paint);// 画出游标.

}

@Override
public boolean onTouchEvent(MotionEvent event) {
//        return super.onTouchEvent(event);
switch (event.getAction())
// 根据动作来执行代码

{
case MotionEvent.ACTION_MOVE:// 滑动
nowX = event.getX();
break;

case MotionEvent.ACTION_DOWN:// 按下

if (event.getX() > bg_on.getWidth() || event.getY() > bg_on.getHeight())
return false;
onSlip = true;
nowX = event.getX();
break;

case MotionEvent.ACTION_CANCEL: // 移到控件外部

onSlip = false;
boolean choose = nowChoose;
if (nowX >= (bg_on.getWidth() / 2))
{
//                    nowX = bg_on.getWidth() - slip_btn.getWidth() / 2;
nowChoose = true;
}
else
{
nowX = nowX - slip_btn.getWidth() / 2;
nowChoose = false;
}
if (changeListener!=null && (choose != nowChoose)) // 调用监听方法
changeListener.onChanged(nowChoose);
break;
case MotionEvent.ACTION_UP:// 松开

onSlip = false;
boolean preChoose = nowChoose;

if (event.getX() >= (bg_on.getWidth() / 2))
{
//                    nowX = bg_on.getWidth() - slip_btn.getWidth() / 2;
nowChoose = true;
}

else
{
nowX = nowX - slip_btn.getWidth() / 2;
nowChoose = false;
}

if (changeListener!=null && (preChoose != nowChoose)) // 调用监听方法
changeListener.onChanged(nowChoose);
break;
default:
}
invalidate();// 重画控件
return true;
}

public void setOnChangedListener(OnChangedListener l)
{
changeListener = l;
}

public interface OnChangedListener
{
abstract void onChanged(boolean checkState);
}

public void setState(boolean isChecked)
{
nowChoose = isChecked;
invalidate();
}

public boolean getState()
{
return this.nowChoose;
}
}


下载地址:http://download.csdn.net/detail/zxc123e/9636210

下面修改一下,来做一个在滑动时按钮背景颜色会发生渐变的效果,参考前面的文章 仿微信6.x底部指示器渐变效果,实现代码如下:

package com.chm.web.view;

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.chm.web.R;

/**
* Created by charmingfst on 2016/9/20.
*/
public class SlipButton extends View
{
private boolean nowChoose = false;// 记录当前按钮是否打开,true为打开,flase为关闭

private boolean onSlip = false;// 记录是否在滑动

private float nowX;// 当前的x

private OnChangedListener changeListener;

private Bitmap bg, slip_btn;

private Canvas mCanvas;
private Bitmap mBitmap;
private Paint mPaint;
private int mColor; //按钮开时的颜色

private Rect mRect;

public SlipButton(Context context)
{
super(context);
init();
}

public SlipButton(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}

public SlipButton(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init();
}

private void init()
{// 初始化

bg = BitmapFactory.decodeResource(getResources(), R.drawable.split_right_1);
slip_btn = BitmapFactory.decodeResource(getResources(), R.drawable.dian);
mColor = 0xff00ff00;
mRect = new Rect(0,0, bg.getWidth(),bg.getHeight());

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        setMeasuredDimension(bg.getWidth(), bg.getHeight());
int width = measureDimension(bg.getWidth(), widthMeasureSpec);
int height = measureDimension(bg.getHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}

public int measureDimension(int expriedSize, int measureSpec){
int result;

int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

if(specMode == MeasureSpec.EXACTLY){
result = specSize;
}else{
result = expriedSize;   //UNSPECIFIED
if(specMode == MeasureSpec.AT_MOST){
result = Math.min(result, specSize);
}
}
return result;
}
@Override
protected void onDraw(Canvas canvas)
{

super.onDraw(canvas);

float x; //滑动点到左边的距离
canvas.drawBitmap(bg,0,0, null);
if (onSlip)// 是否是在滑动状态,
{

float ratio = nowX/(bg.getWidth() - slip_btn.getWidth() / 2);;
int alpha = (int) (ratio*255);
if (alpha >= 0 && alpha<=255)
{
setTargetBitmap(alpha);

}
canvas.drawBitmap(mBitmap, 0, 0, null);

//计算游标距离
if (nowX >= bg.getWidth())// 是否划出指定范围,不能让游标跑到外头,必须做这个判断

x = bg.getWidth() - slip_btn.getWidth() / 2;// 减去游标1/2的长度...

else if (nowX < 0)
{
x = 0;
}
else
{
x = nowX - slip_btn.getWidth() / 2;
}

}
else
{// 非滑动状态

if (nowChoose)// 根据现在的开关状态设置画游标的位置
{
x = bg.getWidth() - slip_btn.getWidth();
setTargetBitmap(255);

}
else
{
x = 0;
setTargetBitmap(0);
}
canvas.drawBitmap(mBitmap, 0, 0, null);

}

if (x < 0)// 对游标位置进行异常判断...
x = 0;
else if (x > bg.getWidth() - slip_btn.getWidth())
x = bg.getWidth() - slip_btn.getWidth();
canvas.drawBitmap(slip_btn, x, 0, null);// 画出游标.

}

private void setTargetBitmap(int alpha) {
mBitmap = Bitmap.createBitmap(getMeasuredWidth(),getMeasuredHeight(), Bitmap.Config.ARGB_8888);
//以bitmap对象创建一个画布,则将内容都绘制在bitmap上,bitmap不得为null;
mCanvas = new Canvas((mBitmap));
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setAntiAlias(true);
mPaint.setDither(true); //设置防抖动,效果更柔和
mPaint.setAlpha(alpha);
mCanvas.drawRect(mRect,mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAlpha(255);
mCanvas.drawBitmap(bg,null,mRect,mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//        return super.onTouchEvent(event);
switch (event.getAction())
// 根据动作来执行代码

{
case MotionEvent.ACTION_MOVE:// 滑动
nowX = event.getX();
break;

case MotionEvent.ACTION_DOWN:// 按下

if (event.getX() > bg.getWidth() || event.getY() > bg.getHeight())
return false;
onSlip = true;
nowX = event.getX();
break;

case MotionEvent.ACTION_CANCEL: // 移到控件外部

onSlip = false;
return true;
case MotionEvent.ACTION_UP:// 松开

onSlip = false;
boolean preChoose = nowChoose;
nowX = event.getX();
if (event.getX() >= (bg.getWidth() / 2))
{
nowChoose = true;
}
else
{
nowChoose = false;
}

if (changeListener!=null && (preChoose != nowChoose)) // 调用监听方法
changeListener.onChanged(nowChoose);
break;
default:
}
invalidate();// 重画控件
return true;
}

public void setOnChangedListener(OnChangedListener l)
{
changeListener = l;
}

public interface OnChangedListener
{
abstract void onChanged(boolean checkState);
}

public void setState(boolean isChecked)
{
nowChoose = isChecked;
invalidate();
}

public boolean getState()
{
return this.nowChoose;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: