黄石网站制作,黑龙江网站备案查询,wordpress的cdn加速,网站开发软件平台有哪些背景是我们有需求#xff0c;做类似ios中开关的按钮。github上有一些开源项目#xff0c;比如 SwitchButton#xff0c; 但是这个项目中提供了很多选项#xff0c;并且实际使用中会出现一些奇怪的问题。
我调整了下代码#xff0c;把无关的功能都给删了#xff0c;保留核…背景是我们有需求做类似ios中开关的按钮。github上有一些开源项目比如 SwitchButton 但是这个项目中提供了很多选项并且实际使用中会出现一些奇怪的问题。
我调整了下代码把无关的功能都给删了保留核心的功能大概这样。 package org.yeshen.widget;// 修改自https://github.com/zcweng/SwitchButton
// 菜单中的类似iOS中开关的样式import static org.yeshen.widget.YsSwitchButton.ANIMATE.*;import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Checkable;public final class YsSwitchButton extends View implements Checkable {private static final int DEFAULT_WIDTH dp2pxInt(44);private static final int DEFAULT_HEIGHT dp2pxInt(25);private static final int DEFAULT_BUTTON_PADDING dp2pxInt(8);private final int uncheckColor 0xFFFF0000;private final int checkedColor 0xFF0000FF;private final int uncheckButtonColor Color.WHITE;private float viewRadius;private float left;private float top;private float right;private float bottom;private float centerY;private float buttonMinX;private float buttonMaxX;private final Paint buttonPaint;private final Paint paint;private final ViewState viewState;private final ViewState beforeState;private final ViewState afterState;private final RectF rect new RectF();private ANIMATE animateState ANIMATE_STATE_NONE;private final ValueAnimator valueAnimator;private final android.animation.ArgbEvaluator argbEvaluator new android.animation.ArgbEvaluator();private boolean isChecked false;private boolean isTouchingDown false;private boolean isUiInit false;private boolean isEventBroadcast false;private OnCheckedChangeListener onCheckedChangeListener;private long touchDownTime;private boolean switchByUser;public YsSwitchButton(Context context) {this(context, null);}public YsSwitchButton(Context context, AttributeSet attrs) {this(context, attrs, 0);}public YsSwitchButton(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paint new Paint(Paint.ANTI_ALIAS_FLAG);buttonPaint new Paint(Paint.ANTI_ALIAS_FLAG);buttonPaint.setColor(uncheckButtonColor);viewState new ViewState();beforeState new ViewState();afterState new ViewState();valueAnimator ValueAnimator.ofFloat(0f, 1f);valueAnimator.setDuration(300);valueAnimator.setRepeatCount(0);ValueAnimator.AnimatorUpdateListener animatorUpdateListener animation - {float value (Float) animation.getAnimatedValue();switch (animateState) {case ANIMATE_STATE_PENDING_SETTLE: {}case ANIMATE_STATE_PENDING_RESET: {}case ANIMATE_STATE_PENDING_DRAG: {if (animateState ! ANIMATE_STATE_PENDING_DRAG) {viewState.buttonX beforeState.buttonX (afterState.buttonX - beforeState.buttonX) * value;}viewState.checkStateColor (int) argbEvaluator.evaluate(value, beforeState.checkStateColor, afterState.checkStateColor);break;}case ANIMATE_STATE_SWITCH: {viewState.buttonX beforeState.buttonX (afterState.buttonX - beforeState.buttonX) * value;float fraction (viewState.buttonX - buttonMinX) / (buttonMaxX - buttonMinX);viewState.checkStateColor (int) argbEvaluator.evaluate(fraction, uncheckColor, checkedColor);break;}default:case ANIMATE_STATE_DRAGING: {}case ANIMATE_STATE_NONE: {break;}}postInvalidate();};valueAnimator.addUpdateListener(animatorUpdateListener);Animator.AnimatorListener animatorListener new Animator.AnimatorListener() {Overridepublic void onAnimationStart(Animator animation) {}Overridepublic void onAnimationEnd(Animator animation) {switch (animateState) {case ANIMATE_STATE_PENDING_DRAG: {animateState ANIMATE_STATE_DRAGING;postInvalidate();break;}case ANIMATE_STATE_PENDING_RESET: {animateState ANIMATE_STATE_NONE;postInvalidate();break;}case ANIMATE_STATE_PENDING_SETTLE: {animateState ANIMATE_STATE_NONE;postInvalidate();broadcastEvent(true);break;}case ANIMATE_STATE_SWITCH: {isChecked !isChecked;animateState ANIMATE_STATE_NONE;postInvalidate();broadcastEvent(switchByUser);break;}case ANIMATE_STATE_DRAGING:case ANIMATE_STATE_NONE:default: {break;}}}Overridepublic void onAnimationCancel(Animator animation) {}Overridepublic void onAnimationRepeat(Animator animation) {}};valueAnimator.addListener(animatorListener);super.setClickable(true);this.setPadding(0, 0, 0, 0);setLayerType(LAYER_TYPE_SOFTWARE, null);}Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {final int widthMode MeasureSpec.getMode(widthMeasureSpec);final int heightMode MeasureSpec.getMode(heightMeasureSpec);if (widthMode MeasureSpec.UNSPECIFIED || widthMode MeasureSpec.AT_MOST) {widthMeasureSpec MeasureSpec.makeMeasureSpec(DEFAULT_WIDTH, MeasureSpec.EXACTLY);}if (heightMode MeasureSpec.UNSPECIFIED || heightMode MeasureSpec.AT_MOST) {heightMeasureSpec MeasureSpec.makeMeasureSpec(DEFAULT_HEIGHT, MeasureSpec.EXACTLY);}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);float viewPadding 0;float height h - viewPadding - viewPadding;viewRadius height * .5f;left viewPadding;top viewPadding;right w - viewPadding;bottom h - viewPadding;centerY (top bottom) * .5f;buttonMinX left viewRadius;buttonMaxX right - viewRadius;if (isChecked()) {setCheckedViewState(viewState);} else {setUncheckViewState(viewState);}isUiInit true;postInvalidate();}private void setUncheckViewState(ViewState viewState) {viewState.checkStateColor uncheckColor;viewState.buttonX buttonMinX;buttonPaint.setColor(uncheckButtonColor);}private void setCheckedViewState(ViewState viewState) {viewState.checkStateColor checkedColor;viewState.buttonX buttonMaxX;int checkedButtonColor Color.WHITE;buttonPaint.setColor(checkedButtonColor);}Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// background colorpaint.setColor(uncheckColor);drawRoundRect(canvas, left, top, right, bottom, viewRadius, paint);// select colorpaint.setColor(viewState.checkStateColor);drawRoundRect(canvas, left, top, right, bottom, viewRadius, paint);// buttoncanvas.drawCircle(viewState.buttonX, centerY,viewRadius - DEFAULT_BUTTON_PADDING / 2F, buttonPaint);}SuppressLint(ObsoleteSdkInt)private void drawRoundRect(Canvas canvas, float left, float top, float right,float bottom, float backgroundRadius, Paint paint) {if (Build.VERSION.SDK_INT Build.VERSION_CODES.LOLLIPOP) {canvas.drawRoundRect(left, top, right, bottom, backgroundRadius, backgroundRadius, paint);} else {rect.set(left, top, right, bottom);canvas.drawRoundRect(rect, backgroundRadius, backgroundRadius, paint);}}Overridepublic void setChecked(boolean checked) {if (checked isChecked()) {postInvalidate();return;}toggle(true, false);}Overridepublic boolean isChecked() {return isChecked;}Overridepublic void toggle() {toggle(true);}public void toggle(boolean animate) {toggle(animate, true);}private void toggle(boolean animate, boolean broadcast) {toggle(animate, broadcast, false);}private void toggle(boolean animate, boolean broadcast, boolean byUser) {if (!isEnabled()) {return;}if (isEventBroadcast) {throw new RuntimeException(should NOT switch the state in method: [onCheckedChanged]!);}if (!isUiInit) {isChecked !isChecked;if (broadcast) {broadcastEvent(byUser);}return;}if (valueAnimator.isRunning()) {valueAnimator.cancel();}if (!animate) {isChecked !isChecked;if (isChecked()) {setCheckedViewState(viewState);} else {setUncheckViewState(viewState);}postInvalidate();if (broadcast) {broadcastEvent(byUser);}return;}animateState ANIMATE_STATE_SWITCH;switchByUser byUser;beforeState.copy(viewState);if (isChecked()) {setUncheckViewState(afterState);} else {setCheckedViewState(afterState);}valueAnimator.start();}private void broadcastEvent(boolean byUser) {if (onCheckedChangeListener ! null) {isEventBroadcast true;onCheckedChangeListener.onCheckedChanged(this, isChecked(), byUser);}isEventBroadcast false;}SuppressLint(ClickableViewAccessibility)Overridepublic boolean onTouchEvent(MotionEvent event) {if (!isEnabled()) {return false;}int actionMasked event.getActionMasked();switch (actionMasked) {case MotionEvent.ACTION_DOWN: {isTouchingDown true;touchDownTime System.currentTimeMillis();removeCallbacks(postPendingDrag);postDelayed(postPendingDrag, 100);break;}case MotionEvent.ACTION_MOVE: {float eventX event.getX();if (isPendingDragState()) {float fraction eventX / getWidth();fraction Math.max(0f, Math.min(1f, fraction));viewState.buttonX buttonMinX (buttonMaxX - buttonMinX) * fraction;} else if (isDragState()) {float fraction eventX / getWidth();fraction Math.max(0f, Math.min(1f, fraction));viewState.buttonX buttonMinX (buttonMaxX - buttonMinX) * fraction;viewState.checkStateColor (int) argbEvaluator.evaluate(fraction, uncheckColor, checkedColor);postInvalidate();}break;}case MotionEvent.ACTION_UP: {isTouchingDown false;removeCallbacks(postPendingDrag);if (System.currentTimeMillis() - touchDownTime 300) {toggle(true, true, true);} else if (isDragState()) {float eventX event.getX();float fraction eventX / getWidth();fraction Math.max(0f, Math.min(1f, fraction));boolean newCheck fraction .5f;if (newCheck isChecked()) {pendingCancelDragState();} else {isChecked newCheck;pendingSettleState();}} else if (isPendingDragState()) {pendingCancelDragState();}break;}case MotionEvent.ACTION_CANCEL: {isTouchingDown false;removeCallbacks(postPendingDrag);if (isPendingDragState() || isDragState()) {pendingCancelDragState();}break;}}return true;}private final Runnable postPendingDrag () - {if (!isInAnimating()) {pendingDragState();}};private boolean isInAnimating() {return animateState ! ANIMATE_STATE_NONE;}private boolean isPendingDragState() {return animateState ANIMATE_STATE_PENDING_DRAG || animateState ANIMATE_STATE_PENDING_RESET;}private boolean isDragState() {return animateState ANIMATE_STATE_DRAGING;}private void pendingDragState() {if (isInAnimating()) {return;}if (!isTouchingDown) {return;}if (valueAnimator.isRunning()) {valueAnimator.cancel();}animateState ANIMATE_STATE_PENDING_DRAG;beforeState.copy(viewState);afterState.copy(viewState);if (isChecked()) {afterState.checkStateColor checkedColor;afterState.buttonX buttonMaxX;} else {afterState.checkStateColor uncheckColor;afterState.buttonX buttonMinX;}valueAnimator.start();}private void pendingCancelDragState() {if (isDragState() || isPendingDragState()) {if (valueAnimator.isRunning()) {valueAnimator.cancel();}animateState ANIMATE_STATE_PENDING_RESET;beforeState.copy(viewState);if (isChecked()) {setCheckedViewState(afterState);} else {setUncheckViewState(afterState);}valueAnimator.start();}}private void pendingSettleState() {if (valueAnimator.isRunning()) {valueAnimator.cancel();}animateState ANIMATE_STATE_PENDING_SETTLE;beforeState.copy(viewState);if (isChecked()) {setCheckedViewState(afterState);} else {setUncheckViewState(afterState);}valueAnimator.start();}SuppressWarnings(unused)public void setOnCheckedChangeListener(OnCheckedChangeListener l) {onCheckedChangeListener l;}public interface OnCheckedChangeListener {void onCheckedChanged(YsSwitchButton view, boolean isChecked, boolean byUser);}private static float dp2px(float dp) {Resources r Resources.getSystem();return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());}private static int dp2pxInt(float dp) {return (int) dp2px(dp);}private static class ViewState {float buttonX;int checkStateColor;private void copy(ViewState source) {this.buttonX source.buttonX;this.checkStateColor source.checkStateColor;}}enum ANIMATE {ANIMATE_STATE_NONE, ANIMATE_STATE_PENDING_DRAG, ANIMATE_STATE_DRAGING, ANIMATE_STATE_PENDING_RESET, ANIMATE_STATE_PENDING_SETTLE, ANIMATE_STATE_SWITCH;}
}