android仿ios开关按钮
来源:互联网 发布:京东全球购奶粉 知乎 编辑:程序博客网 时间:2024/05/01 03:18
效果图
实现起来比较简单,直接上代码。
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; }}
0 0
- android仿ios开关按钮
- android仿ios开关按钮
- 仿Ios滑动开关按钮
- Android自定义控件——仿ios开关按钮
- Android自定义控件——仿ios开关按钮
- Android自定义控件——仿ios开关按钮
- 最完美的android仿ios开关按钮源码
- Android自定义控件——仿ios开关按钮
- 自定义View:仿ios开关按钮控件
- Css 仿iOS的开关按钮
- android 仿ios开关控件
- Android 仿iOS 开关SwitchButton
- Android 仿iphone的开关按钮
- Android 仿iphone的开关按钮
- Android 仿iphone的开关按钮
- 仿iphone开关按钮
- android仿IOS选择(switch)开关
- android开发仿IOS滑动开关
- Delphi中StrToDateTime函数TFormatSettings参数的使用
- Linq to DataTable 操作
- 锁存器不爱触发器
- php返回json数据
- ASP.NET中使用System.Net.Mail发邮件
- android仿ios开关按钮
- 两个数组之间的冒泡排序
- ----- asp.net传递汉字处理
- easyui datagrid删除指定行checkbox 和禁用
- 第三周项目1 顺序表的基本运算(3)
- C# 遍历循环多维数组
- Lucene.net 搜索引擎技术 及分页
- 2016年 书单
- 多道编程与多用户环境