1. 程式人生 > >仿IOS Switch 開關

仿IOS Switch 開關

百度了半天   最後  靠自己的修改加百度的知識   最終封裝好   mark!!!!!!()

package myview;
/**
 * Created by DZy on 2017/3/22.
 */
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import 
android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.Checkable; public class Switchbutton extends View implements Checkable { private static final int
FILL_COLOR_1 = Color.parseColor("#EEEEEE"); private static final int FILL_COLOR_2 = Color.parseColor("#014d67"); private static final int ANIMATION_DURATION = 200; private static final int OFFSET = 12; private ObjectAnimator processAnimator; private boolean isChecked; private float
process = 0; private float lastX = 0; private float lastProcess = 0; private int fillColor; private boolean isPressed; private Paint cPaint; private Paint fPaint; private Paint mPaint; private RectF rectF = null; public Switchbutton(Context context) { super(context); init(); } public Switchbutton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public Switchbutton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { //AT_MOST或者UNSPECIFIED,即使用者沒有指定寬度時,顯示預設寬度 width = dip2px(getContext(), 128); } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { //AT_MOST或者UNSPECIFIED,即使用者沒有指定高度時,顯示預設高度 height = dip2px(getContext(), 48); } setMeasuredDimension(width, height); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawFrameRoundRect(canvas); drawRect(canvas); drawCircle(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getX(); lastProcess = getProcess(); isPressed = true; break; case MotionEvent.ACTION_MOVE: setProcess(lastProcess + (event.getX() - lastX)/getWidth()); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: isPressed = false; if (lastX==event.getX()) { if (process == 0) { setProcess(1f); }else if (process==1){ setProcess(0f); } }else{ if (getProcess() > 0.5) { setProcess(1f); } else { setProcess(0f); } } break; default: break; } return true; } @Override public void setChecked(boolean b) { if (isChecked != b) { isChecked = b; animateSwitch(isChecked); } } @Override public boolean isChecked() { return isChecked; } @Override public void toggle() { setChecked(!isChecked); } /** * 初始化 */ private void init() { isPressed = false; isChecked = false; fillColor = FILL_COLOR_1; setLayerType(LAYER_TYPE_SOFTWARE, null); initAnimation(); initPaint(); // this.setOnClickListener(new OnClickListener() { // @Override // public void onClick(View v) { // if (process == 0) // { // setProcess(1f); // }else if (process==1){ // setProcess(0f); // } // } // }); } /** * 初始化動畫物件 */ private void initAnimation() { processAnimator = ObjectAnimator.ofFloat(this, "process", 0, 1); processAnimator.setDuration(ANIMATION_DURATION); processAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); } /** * 初始化畫筆 */ private void initPaint() { //填充畫筆 mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(0); mPaint.setStyle(Paint.Style.FILL); //frame畫筆 fPaint = new Paint(); fPaint.setAntiAlias(true); fPaint.setColor(Color.parseColor("#BDBDBD")); fPaint.setAlpha(255); fPaint.setStrokeWidth(1); fPaint.setStyle(Paint.Style.STROKE); //圓圈畫筆 cPaint = new Paint(); cPaint.setAntiAlias(true); cPaint.setStyle(Paint.Style.FILL_AND_STROKE); cPaint.setStrokeWidth(1); cPaint.setColor(Color.WHITE); } public float getProcess() { return process; } /** * 設定滑動的進度 * @param process */ public void setProcess(float process) { if (process >= 1f) { this.process = 1; isChecked = true; } else if (process <= 0f) { this.process = 0; isChecked = false; } else { this.process = process; } if (this.process > 0.5) { fillColor = FILL_COLOR_2; } else { fillColor = FILL_COLOR_1; } { if (process==0) { listener.onStateChanged(isChecked); Log.e( "setProcess: ",isChecked()+"" ); }else if (process==1){ Log.e( "setProcess: ",isChecked()+"" ); listener.onStateChanged(isChecked); } } postInvalidate(); } /** * 開關動畫 * @param checked */ private void animateSwitch(boolean checked) { if (processAnimator.isRunning()) { processAnimator.cancel(); } if (checked) { processAnimator.setFloatValues(process, 1f); } else { processAnimator.setFloatValues(process, 0f); } processAnimator.start(); } /** * 獲取滑動時的alpha* @return */ private int getColorAlpha() { int alpha; if (getProcess() >= 0 && getProcess() < 0.5) { alpha = (int) (255 * (1 - getProcess())); } else { alpha = (int) (255 * getProcess()); } int colorAlpha = Color.alpha(fillColor); colorAlpha = colorAlpha * alpha / 255; return colorAlpha; } /** * 繪製填充的色值 * @param canvas */ private void drawRect(Canvas canvas) { mPaint.setARGB(getColorAlpha(), Color.red(fillColor), Color.green(fillColor), Color.blue(fillColor)); if (rectF == null) { rectF = new RectF(OFFSET, OFFSET, getWidth()-OFFSET, getHeight()-OFFSET); } canvas.drawRoundRect(rectF, (getHeight() - OFFSET)/2, (getHeight() - OFFSET)/2, mPaint); } /** * 繪製邊框線條 * @param canvas */ private void drawFrameRoundRect(Canvas canvas) { if (rectF == null) { rectF = new RectF(OFFSET, OFFSET, getWidth()-OFFSET, getHeight()-OFFSET); } canvas.drawRoundRect(rectF, (getHeight() - OFFSET)/2, (getHeight() - OFFSET)/2, fPaint); } /** * 繪製點選的原點 * @param canvas */ private void drawCircle(Canvas canvas) { if (isPressed) { cPaint.setShadowLayer(12, 0, 12, Color.argb(61, 0x00, 0x00, 0x00)); canvas.drawCircle(getHeight()/2 + (getWidth() - getHeight())*process, getHeight()/2, (getHeight() - getHeight()/3)/2 + 6, cPaint); // canvas.drawCircle(getHeight()/2 + (getWidth() - getHeight())*process, getHeight()/2, (getHeight() - getHeight()/3)/2, cPaint); } else { cPaint.setShadowLayer(6, 0, 6, Color.argb(61, 0x00, 0x00, 0x00)); canvas.drawCircle(getHeight()/2 + (getWidth() - getHeight())*process, getHeight()/2, (getHeight() - getHeight()/3)/2, cPaint); } } /** * dip轉換的px * @param context * @param dpValue * @return */ private int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) ((dpValue * scale) + 0.5f); } public interface OnSwitchStateChangedListener { void onStateChanged(boolean state); } private OnSwitchStateChangedListener listener; // = new OnSwitchStateChangedListener() { // @Override // public void onStateChanged(boolean state) { // if (state) // { // Log.e( "onStateChanged: ","" ); // }else{ // Log.e( "onStateChanged: ","" ); // } // } // }; public void setOnSwitchStateChangedListener(OnSwitchStateChangedListener listener) { if (listener != null) { this.listener = listener; } } }