1.
2. Custom Control SwitchView
Public class SwitchView extends View {public static final String TAG = SwitchView. class. getSimpleName (); // state public static final int STATUS_OFF = 0; public static final int STATUS_ON = 1; public static final int STATUS_SCROLING = 2; // private String mOnText = "open"; private String mOffText = "close"; private int mSwitchStatus = STATUS_OFF; private boolean mHasScrolled = false; // indicates whether a rolling private int has occurred. MSrcX = 0, mDstX = 0; private int mBmpWidth = 0; private int mBmpHeight = 0; private int mThumbWidth = 0; private Paint mPaint = new Paint (Paint. ANTI_ALIAS_FLAG); private OnSwitchChangedListener mOnSwitchChangedListener = null; // The Bitmap mSwitch_off, mSwitch_on, listener; public SwitchView (Context context) {this (context, null );} public SwitchView (Context context, AttributeSet attrs) {super (conte Xt, attrs); init ();} public SwitchView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); init ();} // initialize the private void init () {Resources res = getResources (); mSwitch_off = BitmapFactory. decodeResource (res, R. drawable. bg_switch_off); mSwitch_on = BitmapFactory. decodeResource (res, R. drawable. bg_switch_on); mSwitch_thumb = BitmapFactory. decodeResource (res, R. drawable. sw Itch_thumb); mBmpWidth = ceiling (); mBmpHeight = mSwitch_on.getHeight (); mThumbWidth = ceiling () ;}@ Overridepublic void setLayoutParams (LayoutParams params) {params. width = mBmpWidth; params. height = mBmpHeight; super. setLayoutParams (params);}/*** set listener **/public void setOnSwitchChangedListener (OnSwitchChangedListener l) {mOnSwitchChangedListener = l;}/*** set text */public voi D setText (final String onText, final String offText) {mOnText = onText; mOffText = offText; invalidate ();} /*** set the switch status */public void setStatus (boolean on) {mSwitchStatus = (on? STATUS_ON: STATUS_OFF);} @ Overridepublic boolean onTouchEvent (MotionEvent event) {int action = event. getAction (); switch (action) {case MotionEvent. ACTION_DOWN: mSrcX = (int) event. getX (); break; case MotionEvent. ACTION_MOVE: mDstX = Math. max (int) event. getX (), 10); mDstX = Math. min (mDstX, 62); if (mSrcX = mDstX) return true; mHasScrolled = true; AnimationTransRunnable aTransRunnable = new AnimationTransR Unnable (mSrcX, mDstX, 0); new Thread (aTransRunnable ). start (); mSrcX = mDstX; break; case MotionEvent. ACTION_UP: if (mHasScrolled = false) {// if no slide occurs, it means that this is a process of mSwitchStatus = Math. abs (mSwitchStatus-1); int xFrom = 10, xTo = 62; if (mSwitchStatus = STATUS_OFF) {xFrom = 62; xTo = 10 ;} animationTransRunnable runnable = new AnimationTransRunnable (xFrom, xTo, 1); new Thread (runnable ). start ();} else {inv Alidate (); mHasScrolled = false;} // callback event function if (mOnSwitchChangedListener! = Null) {mOnSwitchChangedListener. onSwitchChanged (this, mSwitchStatus);} break; default: break;} return true;} @ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas); // some numerical values are hard-coded internally during the drawing. In fact, it is not very good. // The main reason is that there is a transparent border around the image, so there must be a certain offset // hard-coded value. As long as you understand the code, you can actually understand its meaning and make corresponding improvements. MPaint. setTextSize (14); mPaint. setTypeface (Typeface. DEFAULT_BOLD); if (mSwitchStatus = STATUS_OFF) {drawBitmap (canvas, null, null, mSwitch_off); drawBitmap (canvas, null, null, mSwitch_thumb); mPaint. setColor (Color. rgb (105,105,105); canvas. translate (mSwitch_thumb.getWidth (), 0); canvas. drawText (mOffText, 0, 20, mPaint);} else if (mSwitchStatus = STATUS_ON) {drawBitmap (canvas, null, null, mSwitch_on ); Int count = canvas. save (); canvas. translate (mSwitch_on.getWidth ()-mSwitch_thumb.getWidth (), 0); drawBitmap (canvas, null, null, mSwitch_thumb); mPaint. setColor (Color. WHITE); canvas. restoreToCount (count); canvas. drawText (mOnText, 17, 20, mPaint);} else {// SWITCH_SCROLINGmSwitchStatus = mDstX> 35? STATUS_ON: STATUS_OFF; drawBitmap (canvas, new Rect (0, 0, mDstX, mBmpHeight), new Rect (0, 0, (int) mDstX, mBmpHeight), mSwitch_on); mPaint. setColor (Color. WHITE); canvas. drawText (mOnText, 17, 20, mPaint); int count = canvas. save (); canvas. translate (mDstX, 0); drawBitmap (canvas, new Rect (mDstX, 0, mBmpWidth, mBmpHeight), new Rect (0, 0, mBmpWidth-mDstX, mBmpHeight), mSwitch_off ); canvas. restoreToCount (coun T); count = canvas. save (); canvas. clipRect (mDstX, 0, mBmpWidth, mBmpHeight); canvas. translate (mThumbWidth, 0); mPaint. setColor (Color. rgb (105,105,105); canvas. drawText (mOffText, 0, 20, mPaint); canvas. restoreToCount (count); count = canvas. save (); canvas. translate (mDstX-mThumbWidth/2, 0); drawBitmap (canvas, null, null, mSwitch_thumb); canvas. restoreToCount (count) ;}} public void drawBitmap (Canvas canvas, Rect src, Rect dst, Bitmap bitmap) {dst = (dst = null? New Rect (0, 0, bitmap. getWidth (), bitmap. getHeight (): dst); Paint paint = new Paint (); canvas. drawBitmap (bitmap, src, dst, paint);}/*** AnimationTransRunnable thread used for slide animation */private class AnimationTransRunnable implements Runnable {private int srcX, dstX; private int duration; public AnimationTransRunnable (float srcX, float dstX, final int duration) {this. srcX = (int) srcX; this. dstX = (int) dstX; thi S. duration = duration;} @ Overridepublic void run () {final int patch = (dstX> srcX? 5:-5); if (duration = 0) {SwitchView. this. mSwitchStatus = STATUS_SCROLING; SwitchView. this. postInvalidate ();} else {int x = srcX + patch; while (Math. abs (x-dstX)> 5) {mDstX = x; SwitchView. this. mSwitchStatus = STATUS_SCROLING; SwitchView. this. postInvalidate (); x + = patch; try {Thread. sleep (10);} catch (InterruptedException e) {e. printStackTrace () ;}} mDstX = dstX; SwitchView. this. mSwitchStatus = mDstX> 35? STATUS_ON: STATUS_OFF; SwitchView. this. postInvalidate () ;}} public static interface OnSwitchChangedListener {public abstract void onSwitchChanged (SwitchView obj, int status );}}
3. Download source code