android 自訂開關(SwitchButton)

來源:互聯網
上載者:User

標籤:styles   android   開關   switchbutton   

最近心血來潮,寫了一個自訂仿iPhone的開關。有需要的同學可以來下載啦。支援點擊自動滾動,速率可以自己根據需要修改。觸摸滾動,大小自訂,支援修改樣式。就不錄製動畫,就上傳了兩張圖給大家看看。

      

主要代碼:

package com.example.switchbutton;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.Resources;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.os.Handler;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;public class SwitchButton extends View {public static final int DEFAULT_WIDTH = 100;public static final int DEFAULT_HEIGTH = 45;public static final int PER_POST_TIME = 20;public static final int CLICK = 0;public static final int LEFT  = 1;public static final int RIGHT  = 2;private int mSelectBg;private int mUnSelectBg;private int mBorderColor;private int mSelectCirlceColor;private int mUnSelectCircleColor;private boolean isChecked;private Paint mPaint;private int mWidth;private int mHeight;private int mClickTimeout;  private int mTouchSlop; private float mAnimMove;private final float VELOCITY = 350;private float firstDownX;private float firstDownY;private float lastDownX;private int mCriclePostion;private int mStartCriclePos;private int mEndCirclePos;private boolean isScroll;private int status;private Handler mHander;private AnimRunnable mAnim;private OnCheckChangeListener mOnCheckChangeListener;public interface OnCheckChangeListener {void OnCheck(SwitchButton switchButton,boolean isChecked);}public SwitchButton(Context context, AttributeSet attrs) {super(context, attrs);Resources res = getResources();int defaultSelectBg = res.getColor(R.color.default_switch_button_select_bg);int defaultUnSelectBg = res.getColor(R.color.default_switch_button_unselect_bg);int defaultBorderColor = res.getColor(R.color.default_switch_button_border_color);int defaultSelectCircleColor = res.getColor(R.color.default_switch_button_select_color);int defaultUnSelectCircleColor = res.getColor(R.color.default_switch_button_unselect_color);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.SwitchButton);mSelectBg = a.getColor(R.styleable.SwitchButton_select_bg, defaultSelectBg);mUnSelectBg = a.getColor(R.styleable.SwitchButton_unselect_bg, defaultUnSelectBg);mBorderColor = a.getColor(R.styleable.SwitchButton_select_border_color, defaultBorderColor);mSelectCirlceColor = a.getColor(R.styleable.SwitchButton_select_cricle_color, defaultSelectCircleColor);mUnSelectCircleColor = a.getColor(R.styleable.SwitchButton_unselect_cricle_color, defaultUnSelectCircleColor);isChecked = a.getBoolean(R.styleable.SwitchButton_isChecked,false);a.recycle();initView(context);}private void initView(Context context) {mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);final float density = getResources().getDisplayMetrics().density;  mAnimMove = (int) (VELOCITY * density + 0.5f) / 150; //自動捲動速度        mClickTimeout = ViewConfiguration.getPressedStateDuration()                  + ViewConfiguration.getTapTimeout();  //點擊時間        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();//觸摸滾動Slop        mHander = new Handler();        mAnim = new AnimRunnable();}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint.setColor(mBorderColor);mPaint.setStyle(Paint.Style.STROKE);RectF rect = new RectF(0, 0, mWidth, mHeight);canvas.drawRoundRect(rect, mHeight/2, mHeight/2, mPaint);mPaint.setColor(isChecked ? mSelectBg :mUnSelectBg);RectF innerRect = new RectF(1, 1, mWidth -1, mHeight -1);canvas.drawRoundRect(innerRect, mHeight/2 -1, mHeight/2 -1, mPaint);mPaint.setColor(isChecked ? mSelectCirlceColor : mUnSelectCircleColor);mPaint.setStyle(Paint.Style.FILL);canvas.drawCircle(mCriclePostion, mHeight/2, mHeight/2 -1, mPaint);}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if(isScroll){return false;}firstDownX = x;firstDownY = y;lastDownX = x;mCriclePostion = isChecked ? mEndCirclePos : mStartCriclePos;break;case MotionEvent.ACTION_MOVE:float delaX = x - lastDownX;setCriclePositon(delaX);lastDownX  = x;invalidate();break;case MotionEvent.ACTION_UP:float totalX = x - firstDownX;float totalY = y - firstDownY;float time = event.getEventTime() - event.getDownTime();if(totalX < mTouchSlop && totalY <mTouchSlop && time < mClickTimeout){status = CLICK;startAutoScroll();}else{delaX = x - lastDownX;setCriclePositon(delaX);status = mCriclePostion < mWidth / 2 ? LEFT :RIGHT;startAutoScroll();}break;}return true;}//開始自動滾動private void startAutoScroll(){isScroll = true;mHander.postDelayed(mAnim, PER_POST_TIME);}class AnimRunnable implements Runnable{@Overridepublic void run() {mHander.postDelayed(this, PER_POST_TIME);moveView();}//移動private void moveView() {if((status == CLICK && isChecked) || status == LEFT){mCriclePostion -= mAnimMove;if(mCriclePostion < mHeight /2){mCriclePostion = mHeight/2;stopView(false);}}else if((status == CLICK && !isChecked) || status == RIGHT) {mCriclePostion += mAnimMove;if(mCriclePostion > mWidth -mHeight /2){mCriclePostion = mWidth -mHeight /2;stopView(true);}}invalidate();}//停止移動Viewprivate void stopView(boolean endChecked) {mHander.removeCallbacks(mAnim);isScroll = false;isChecked = endChecked;//回調監聽事件if(mOnCheckChangeListener != null){mOnCheckChangeListener.OnCheck(SwitchButton.this, isChecked);}}}//設定圓心的位置private synchronized void setCriclePositon(float delaX){int pos = (int) (mCriclePostion + delaX);if(pos < mHeight / 2){mCriclePostion =  mHeight / 2;}else if(pos > mWidth - mHeight /2){mCriclePostion =  mWidth - mHeight /2;}else{mCriclePostion = pos;}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthMode = MeasureSpec.getMode(widthMeasureSpec);if(widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST){mWidth = DEFAULT_WIDTH;}else{mWidth = MeasureSpec.getSize(widthMeasureSpec);}int heightMode = MeasureSpec.getMode(heightMeasureSpec);if(heightMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.AT_MOST){mHeight = DEFAULT_HEIGTH;}else{mHeight = MeasureSpec.getSize(heightMeasureSpec);}mStartCriclePos = mHeight / 2;mEndCirclePos = mWidth - mHeight /2;mCriclePostion = isChecked ? mEndCirclePos :mStartCriclePos; setMeasuredDimension(mWidth, mHeight);}public boolean isChecked() {return isChecked;}public void setChecked(boolean isChecked) {this.isChecked = isChecked;invalidate();}public void setOnCheckChangeListener(OnCheckChangeListener onCheckChangeListener) {this.mOnCheckChangeListener = onCheckChangeListener;}}

attrs:

<?xml version="1.0" encoding="utf-8"?> <resources>     <declare-styleable name="SwitchButton">         <attr name="select_bg" format="color"/>         <attr name="unselect_bg" format="color"/>         <attr name="select_border_color" format="color"/>         <attr name="select_cricle_color" format="color"/>          <attr name="unselect_cricle_color" format="color"/>          <attr name="isChecked" format="boolean"></attr>    </declare-styleable> </resources>

:http://download.csdn.net/detail/huangyanbin123/8173521

android 自訂開關(SwitchButton)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.