先上傳兩張圖檔
代碼實作:
package com.example.animation.view;
import com.example.animation.R;
import com.example.animation.util.CommonUtil;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
//自定義開關
public class SwitchView extends View {
// 開關圓的圖檔
private Bitmap circleBitmap, onBitmap, offBitmap;
private float downX;
private float distanceX;
private float mBitmapWidth;
// 預設開關是開着的
public State mState = State.ON;
private int mWidth, mHeihgt, radius, mStrokeWidth;
public enum State {
ON, OFF
}
public SwitchView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public SwitchView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public SwitchView(Context context) {
super(context);
initView(context);
}
private void initView(Context context) {
radius = CommonUtil.dpToPx(context.getResources(), 20);
mStrokeWidth = CommonUtil.dpToPx(context.getResources(), 1);
circleBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.yuan);
onBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.on_btn);
offBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.off_btn);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
distanceX = 0;
break;
case MotionEvent.ACTION_MOVE:
float moveX = event.getX();
distanceX = moveX - downX;
invalidate();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
downX = 0;
// need to reset the state
// 滑動的距離大于1/2個距離,滑動的距離+1/2個圓的距離》1/2width
float middle = distanceX + mBitmapWidth / 2;
if (middle >= (mWidth / 2)) {
// trun on
changeStateOn();
} else {
// turn off
changeStateOff();
}
break;
default:
break;
}
return true;
}
private void changeStateOff() {
distanceX = 0;
if (mState != State.OFF && mListener != null) {
mListener.onStateChanged(State.OFF);
}
mState = State.OFF;
invalidate();
}
private void changeStateOn() {
distanceX = mWidth - mBitmapWidth;
if (mState != State.ON && mListener != null) {
mListener.onStateChanged(State.ON);
}
mState = State.ON;
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// mWidth = this.getMeasuredWidth();
mWidth = onBitmap.getWidth();
mHeihgt = onBitmap.getHeight();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
mBitmapWidth = circleBitmap.getWidth();
float right = mWidth - mBitmapWidth;
// if right == turn on
if (mState == State.ON) {
distanceX = right + distanceX;
}
if (distanceX < 0) {
distanceX = 0;
}
if (distanceX > right) {
distanceX = right;
}
Paint paint = new Paint();
canvas.drawBitmap(onBitmap, 0, 0, paint);
// canvas.drawBitmap(offBitmap, distanceX, 0, paint);
canvas.drawBitmap(circleBitmap, distanceX, 0, paint);
// 畫圓角矩形
paint.setStyle(Paint.Style.FILL);// 充滿
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);// 設定畫筆的鋸齒效果
RectF oval = new RectF(distanceX, 0, mWidth, mHeihgt);// 設定個新的長方形
canvas.drawRoundRect(oval, radius, radius, paint);// 第二個參數是x半徑,第三個參數是y半徑
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(mStrokeWidth);
paint.setColor(Color.GRAY);
paint.setAntiAlias(true);
RectF oval1 = new RectF(distanceX, 0, mWidth, mHeihgt);// 設定個新的長方形
canvas.drawRoundRect(oval1, radius, radius, paint);// 第二個參數是x半徑,第三個參數是y半徑
super.onDraw(canvas);
}
public void setState(State state) {
this.mState = state;
invalidate();
}
public State getState() {
return mState;
}
public interface StateChangedListener {
void onStateChanged(State nowState);
}
private StateChangedListener mListener;
public void setStateChangedListener(StateChangedListener listener) {
this.mListener = listener;
}
}
源碼下載下傳