The iphone has a switch control, very beautiful, in fact, android4.0 later also have a switch control, but only in the system after 4.0, which lost its use value, and I think its interface is not very good-looking. Recently saw Baidu Magic beat a control, feel very beautiful ah, and then decompile, although not confused, but still difficult to read, and then according to their own ideas wrote a, function and Baidu Magic beat similar.
The following is the effect of Baidu Magic beat and Slideswitch effect
First, the principle
Inherits from the view class, override its OnDraw function, draws two background images (a gray one red) and a switch diagram (circular switch) through the canvas, and override its ontouchevent function to achieve the sliding effect; Finally, open a thread to animate , and realize the effect of slow sliding.
Second, the Code
Slideswitch.java
Package com.example.hellojni;
Import Android.content.Context;
Import android.content.res.Resources;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.Rect;
Import Android.graphics.Typeface;
Import Android.util.AttributeSet;
Import Android.util.Log;
Import android.view.MotionEvent;
Import Android.view.View;
Import Android.view.ViewGroup.LayoutParams; /** * Slideswitch Imitation iphone sliding switch components, imitation Baidu Magic Figure slide switch components * Components are divided into three states: open, close, sliding <br/> * Use method: * <pre>slideswitch
Slideswitch = new Slideswitch (this);
*slideswitch.setonswitchchangedlistener (Onswitchchangedlistener);
*linearlayout.addview (Slideswitch); </pre> Note: can also be loaded in XML using * @author Scott * * * * * public class Slideswitch extends View {public static final
String TAG = "Slideswitch"; public static final int switch_off = 0;//shutdown state public static final INT switch_on = 1;//Open state public static final int switch_scroling = 2;//scrolling state//text for display private String Montext =
"Open";
Private String Mofftext = "Off";
private int mswitchstatus = Switch_off;
Private Boolean mhasscrolled = false;//indicates if scrolling private int 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;
Switch state diagram Bitmap Mswitch_off, mswitch_on, Mswitch_thumb;
Public Slideswitch {This (context, NULL);
Public Slideswitch (context, AttributeSet attrs) {Super (context, attrs);
Init ();
Public Slideswitch (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
Init (); //Initialize three pictures 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.switch_thumb);
Mbmpwidth = Mswitch_on.getwidth ();
Mbmpheight = Mswitch_on.getheight ();
Mthumbwidth = Mswitch_thumb.getwidth ();
@Override public void Setlayoutparams (Layoutparams params) {params.width = Mbmpwidth;
Params.height = Mbmpheight;
Super.setlayoutparams (params); /** * Set state change listening function for switch control * @param onswitchchangedlistener See {@link Onswitchchangedlistener}/Publi c void Setonswitchchangedlistener (Onswitchchangedlistener onswitchchangedlistener) {Monswitchchangedlistener = on
Switchchangedlistener; /** * Set switch above text * @param the text to display when the Ontext control is opened * @param the text to display when the control is turned off * * public void Settex T (final string ontext, final string offtext) {mOntext = Ontext;
Mofftext =offtext;
Invalidate (); /** * Set the state of the switch * @param on whether to open the switch turned on to true close to false */public void SetStatus (Boolean on) {m Switchstatus = (on?
Switch_on:switch_off);
@Override public boolean ontouchevent (Motionevent event) {int action = event.getaction ();
LOG.D (TAG, "ontouchevent x=" + event.getx ());
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 Animationtransrunnable (MSRCX, MDSTX, 0);
New Thread (atransrunnable). Start ();
MSRCX = MDSTX;
Break Case MotionEvent.ACTION_UP:if (mhasscrolled = = false)//If no slip has occurred, it means that this is a single click process {mswitchstatus = MatH.abs (MSWITCHSTATUS-1);
int xfrom = ten, xTo = 62;
if (Mswitchstatus = = Switch_off) {Xfrom = 62;
XTo = 10;
} animationtransrunnable runnable = new Animationtransrunnable (Xfrom, XTo, 1);
New Thread (runnable). Start ();
else {invalidate ();
mhasscrolled = false; }//Status change callback event function if (Monswitchchangedlistener!= null) {MONSWITCHCHANGEDLISTENER.ONSWITCHC
Hanged (this, mswitchstatus);
} break;
Default:break;
return true; @Override protected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, old
W, OLDH);
} @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
There are some numerical hard codes used inside the drawing. Actually not very good,//mainly considering the picture reason, the picture has the transparent boundary, therefore must have the offset//hard coding the numerical value as long as understands the code, actually may understand its meaning, may make the corresponding improvement.
Mpaint.settextsize (14); Mpaint.settypefAce (Typeface.default_bold);
if (Mswitchstatus = = Switch_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, Mpaint);
else if (mswitchstatus = = switch_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, mpaint); else//switch_scroling {mswitchstatus = mdstx > 35?
Switch_on:switch_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, 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 (count);
Count = Canvas.save ();
Canvas.cliprect (mdstx, 0, Mbmpwidth, mbmpheight);
Canvas.translate (mthumbwidth, 0);
Mpaint.setcolor (Color.rgb (105, 105, 105));
Canvas.drawtext (mofftext, 0, 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 The thread used for sliding animations * * Private class Animationtransrunnable implements Runnable
{private int srcx, DSTX;
private int duration;
/** * Sliding animation * @param SRCX sliding starting point * @param dstx sliding termination point * @param duration animation, 1 use, 0 do not use * *
Public animationtransrunnable (float srcx, float dstx, final int duration) {THIS.SRCX = (int) srcx;
THIS.DSTX = (int) dstx;
this.duration = Duration;
@Override public void Run () {final int patch = (Dstx > SRCX 5:-5);
if (Duration = = 0) {SlideSwitch.this.mSwitchStatus = switch_scroling;
SlideSwitch.this.postInvalidate ();
else {log.d (TAG, "Start Animation: [+ SRCX +", "+ Dstx +]");
int x = SRCX + patch;
while (Math.Abs (X-DSTX) > 5) {mdstx = x;
SlideSwitch.this.mSwitchStatus = switch_scroling; SlideSwitch.this.postInvalidate ();
x + + patch;
try {thread.sleep (10);
catch (Interruptedexception e) {e.printstacktrace ();
} MDSTX = Dstx; SlideSwitch.this.mSwitchStatus = mdstx > 35?
Switch_on:switch_off;
SlideSwitch.this.postInvalidate (); }} public static interface Onswitchchangedlistener {/** * state change callback function * @param status
switch_on says open Switch_off means close/public abstract void onswitchchanged (Slideswitch obj, int status);
}
}
Layout XML
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/" Android "Android:layout_width=" "Fill_parent" android:layout_height= "fill_parent" android:background= "#fdfdfd" a
ndroid:orientation= "vertical" android:paddingleft= "10dip" android:paddingright= "10dip" > <imageview Android:id= "@+id/imageview1" android:layout_width= "fill_parent" android:layout_height= "Wrap_content" Androi d:src= "@drawable/top"/> <relativelayout android:layout_width= "Fill_parent" android:layout_height=
Ap_content "> <textview android:id=" @+id/textview1 "android:layout_width=" Wrap_content " android:layout_height= "Wrap_content" android:layout_alignparentleft= "true" android:layout_centervertical= "tr UE "android:text=" Network composition "android:textsize=" 15sp "/> <com.example.hellojni.slideswitch and
Roid:id= "@+id/slideswitch1" Android:layout_width= "116dip" android:layout_height= "46dip" android:layout_alignparentright= "true" Android:layout_centervertical= "true"/> </RelativeLayout> <relativelayout android:layout_width= "
Fill_parent "android:layout_height=" wrap_content "> <textview android:id=" @+id/textview2 " Android:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:layout_alignparentleft= "Tru" E "android:layout_centervertical=" true "android:text=" preserve original artwork "android:textsize=" 15sp "/> < Com.example.hellojni.SlideSwitch android:id= "@+id/slideswitch2" android:layout_width= "116dip" Android
: layout_height= "46dip" android:layout_alignparentright= "true" android:layout_centervertical= "true"/> </RelativeLayout> <relativelayout android:layout_width= "fill_parent" android:layout_height= "Wrap_c Ontent "> <TextView android:id= "@+id/textview3" android:layout_width= wrap_content "android:layout_height=" Wrap_ Content "android:layout_alignparentleft=" true "android:layout_centervertical=" true "android:text=" photo sound
Tone "android:textsize=" 15sp "/> <com.example.hellojni.slideswitch android:id=" @+id/slideswitch3 "
Android:layout_width= "116px" android:layout_height= "46px" android:layout_alignparentright= "true" Android:layout_centervertical= "true"/> </RelativeLayout> <textview android:id= "@+id/textviewt IP "android:layout_width=" fill_parent "android:layout_height=" wrap_content "android:gravity=" center "a
ndroid:text= "TextView"/> </LinearLayout>
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.