Android Custom Switchbutton Switch controls

Source: Internet
Author: User

The Switchbutton switch control is already very popular. There are a variety of styles, Switchbutton switch controls are typically used for app settings there, control caching, sounds, prompts, downloads, and more. is a good UI experience and a user's habitual. Then here is a Switchbutton switch control. and attach the source code.

SOURCE Download: click

First, see the realization of the


Second, custom Switchbutton

This is a Switchbutton class that inherits the checkbox. To achieve these animations, first prepare the pictures, and then canvas to draw the controls ' borders, backgrounds, and buttons. When drawing, add the corresponding picture. Then use the Ontouchevent function to accept the effect when pressed, slid, and loosened. Then it's probably out. Next look at the specific code.

Package Com.org.switchbtn;import Com.switchbutton.activity.r;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.porterduff;import Android.graphics.porterduffxfermode;import Android.graphics.RectF;import Android.util.attributeset;import Android.view.motionevent;import Android.view.viewconfiguration;import Android.view.viewparent;import Android.widget.checkbox;public class Switchbutton extends CheckBox {private Paint Mpain    T    Private Viewparent mparent;    Private Bitmap Mbottom;    Private Bitmap mcurbtnpic;    Private Bitmap mbtnpressed;    Private Bitmap Mbtnnormal;    Private Bitmap Mframe;    Private Bitmap Mmask;    Private RECTF MSAVELAYERRECTF;    Private Porterduffxfermode Mxfermode; private float Mfirstdowny; The first press of the Y private float mfirstdownx; First press of X private FLOat Mrealpos; The drawing position of the picture is private float mbtnpos; The position of the button is private float mbtnonpos; The switch opens the position of the private float mbtnoffpos;    Switch off the position of the private float mmaskwidth;    private float mmaskheight;    private float mbtnwidth;    private float Mbtninitpos;    private int mclicktimeout;    private int mtouchslop;    Private final int max_alpha = 255;    private int malpha = Max_alpha;    Private Boolean mchecked = false;    Private Boolean mbroadcasting;    Private Boolean Mturningon;    Private PerformClick Mperformclick;    Private Oncheckedchangelistener Moncheckedchangelistener;    Private Oncheckedchangelistener Moncheckedchangewidgetlistener;    Private Boolean manimating;    Private final float VELOCITY = 350;    private float mvelocity;    Private final float extended_offset_y = 15; private float mextendoffsety;    The area of the Y axis expands, increasing the click Area Private float manimationposition;    private float manimatedvelocity; Public Switchbutton (context context, AttributeSet Attrs) {This (Context, Attrs, Android.    R.attr.checkboxstyle);    } public Switchbutton (context context) {This (context, NULL);        } public Switchbutton (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);    Initview (context);        } private void Initview (context context) {Mpaint = new Paint ();        Mpaint.setcolor (Color.White);        Resources resources = Context.getresources (); Get viewconfiguration mclicktimeout = viewconfiguration.getpressedstateduration () + Viewconfigura        Tion.gettaptimeout ();        Mtouchslop = Viewconfiguration.get (context). Getscaledtouchslop ();        Get Bitmap Mbottom = bitmapfactory.decoderesource (resources, R.drawable.bottom);        mbtnpressed = Bitmapfactory.decoderesource (resources, r.drawable.btn_pressed);        Mbtnnormal = Bitmapfactory.decoderesource (resources, r.drawable.btn_unpressed); Mframe = Bitmapfactory.decoderesource (Resources, R.DRAWABLE.FRame);        Mmask = Bitmapfactory.decoderesource (resources, R.drawable.mask);        Mcurbtnpic = Mbtnnormal;        Mbtnwidth = Mbtnpressed.getwidth ();        Mmaskwidth = Mmask.getwidth ();        Mmaskheight = Mmask.getheight ();        Mbtnoffpos = MBTNWIDTH/2;        Mbtnonpos = MMASKWIDTH-MBTNWIDTH/2; Mbtnpos = mchecked?        Mbtnonpos:mbtnoffpos;        Mrealpos = Getrealpos (Mbtnpos);        Final float density = getresources (). Getdisplaymetrics (). density;        mvelocity = (int) (VELOCITY * density + 0.5f);        mextendoffsety = (int) (extended_offset_y * density + 0.5f);        MSAVELAYERRECTF = new RECTF (0, Mextendoffsety, Mmask.getwidth (), mmask.getheight () + mextendoffsety);    Mxfermode = new Porterduffxfermode (PorterDuff.Mode.SRC_IN); } @Override public void SetEnabled (Boolean enabled) {Malpha = enabled?        MAX_ALPHA:MAX_ALPHA/2;    super.setenabled (enabled); } public boolean isChecked () {return McheckeD    } public void Toggle () {setchecked (!mchecked); /** * Internally calls this method to set the checked state, this method delays the execution of various callback functions, guaranteeing the smoothness of the animation * * @param checked */private void Setcheckeddel                 Ayed (Final Boolean checked) {this.postdelayed (new Runnable () {@Override public void run () {            setchecked (checked);    }}, 10);     }/** * <p> * Changes the checked state of this button. * </p> * * @param checked true to check the button, false to uncheck it */public void setchecked (bo            Olean checked) {if (mchecked! = checked) {mchecked = checked; Mbtnpos = checked?            Mbtnonpos:mbtnoffpos;            Mrealpos = Getrealpos (Mbtnpos);            Invalidate ();                Avoid Infinite recursions If setchecked () is called from A//listener if (mbroadcasting) {            Return            } mbroadcasting = true; if (MonchEckedchangelistener = null) {moncheckedchangelistener.oncheckedchanged (switchbutton.this, mChecked); } if (Moncheckedchangewidgetlistener! = null) {moncheckedchangewidgetlistener.onchecked            Changed (Switchbutton.this, mchecked);        } mbroadcasting = false;     }}/** * Register a callback to being invoked when the checked state of this button * changes. * * @param listener the callback to call on checked state change */public void Setoncheckedchangelistener (OnC    Heckedchangelistener listener) {Moncheckedchangelistener = listener; }/** * Register a callback to being invoked when the checked state of this button * changes.     This callback are used for internal purpose only. * * @param listener The callback to the checked state change * @hide */void Setoncheckedchangewidgetl Istener (Oncheckedchangelistener listener) {MoncheckedchangewidgetliStener = listener;        } @Override public boolean ontouchevent (Motionevent event) {int action = event.getaction ();        float x = Event.getx ();        Float y = event.gety ();        float deltax = Math.Abs (X-MFIRSTDOWNX);        float DeltaY = Math.Abs (Y-mfirstdowny);                Switch (action) {case MotionEvent.ACTION_DOWN:attemptClaimDrag ();                Mfirstdownx = x;                Mfirstdowny = y;                Mcurbtnpic = mbtnpressed; Mbtninitpos = mchecked?                Mbtnonpos:mbtnoffpos;            Break                Case MotionEvent.ACTION_MOVE:float time = Event.geteventtime ()-event.getdowntime ();                Mbtnpos = Mbtninitpos + event.getx ()-mfirstdownx;                if (Mbtnpos >= mbtnoffpos) {mbtnpos = Mbtnoffpos;                } if (Mbtnpos <= mbtnonpos) {mbtnpos = Mbtnonpos; } Mturningon = MBtnPos > (Mbtnoffpos-mbtnonpos)/2 + Mbtnonpos;                Mrealpos = Getrealpos (Mbtnpos);            Break                Case MotionEvent.ACTION_UP:mCurBtnPic = Mbtnnormal;                Time = Event.geteventtime ()-event.getdowntime (); if (DeltaY < Mtouchslop && DeltaX < Mtouchslop && Time < Mclicktimeout) {if (                    Mperformclick = = null) {Mperformclick = new PerformClick ();                    } if (!post (Mperformclick)) {PerformClick ();                }} else {startanimation (!mturningon);        } break;        } invalidate ();    return isenabled ();        } Private Final class PerformClick implements Runnable {public void run () {PerformClick ();      }} @Override public boolean PerformClick () {startanimation (!mchecked);  return true;  }/** * Tries to claim the user's drag motion, and requests disallowing any * ancestors from stealing events in     The drag.        */private void Attemptclaimdrag () {mparent = GetParent ();        if (mparent! = null) {mparent.requestdisallowintercepttouchevent (true); }}/** * Convert Btnpos to Realpos * * @param btnpos * @return */private float getrealpos (float BT    NPos) {return BTNPOS-MBTNWIDTH/2; } @Override protected void OnDraw (canvas canvas) {Canvas.savelayeralpha (MSAVELAYERRECTF, Malpha, Canvas.matr Ix_save_flag | Canvas.clip_save_flag | Canvas.has_alpha_layer_save_flag | Canvas.full_color_layer_save_flag |        Canvas.clip_to_layer_save_flag);        Draw Mask Canvas.drawbitmap (mmask, 0, Mextendoffsety, mpaint);        Mpaint.setxfermode (Mxfermode);        Draw bottom Picture Canvas.drawbitmap (Mbottom, Mrealpos, Mextendoffsety, Mpaint); MpainT.setxfermode (NULL);        Draw Border Canvas.drawbitmap (mframe, 0, Mextendoffsety, mpaint);        Draw button Canvas.drawbitmap (Mcurbtnpic, Mrealpos, Mextendoffsety, Mpaint);    Canvas.restore (); } @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {setmeasureddimension (int    ) mmaskwidth, (int) (Mmaskheight + 2 * mextendoffsety));        } private void Startanimation (Boolean turnOn) {manimating = true; Manimatedvelocity = TurnOn?        -mvelocity:mvelocity;        Manimationposition = Mbtnpos;    New Switchanimation (). run ();    } private void StopAnimation () {manimating = false; Private Final class Switchanimation implements Runnable {@Override public void run () {if (            !manimating) {return;            } doanimation ();        Frameanimationcontroller.requestanimationframe (this); }} private void Doanimation () {manimationPosition + = manimatedvelocity * frameanimationcontroller.animation_frame_duration/1000;            if (manimationposition <= mbtnonpos) {stopanimation ();            Manimationposition = Mbtnonpos;        Setcheckeddelayed (TRUE);            } else if (manimationposition >= mbtnoffpos) {stopanimation ();            Manimationposition = Mbtnoffpos;        Setcheckeddelayed (FALSE);    } moveview (Manimationposition);        } private void Moveview (float position) {mbtnpos = position;        Mrealpos = Getrealpos (Mbtnpos);    Invalidate (); }}

Second, the control auxiliary class Frameanimationcontroller

package com.org.switchbtn;import android.os.handler;import android.os.Message; public class Frameanimationcontroller {private static final int msg_animate = 1000;public static final int animation_frame _duration = 1000/60;private static final Handler Mhandler = new Animationhandler ();p rivate Frameanimationcontroller () {T Hrow new Unsupportedoperationexception ();} public static void Requestanimationframe (Runnable Runnable) {Message message = new Message (); message.what = Msg_animate;m Essage.obj = runnable;mhandler.sendmessagedelayed (message, animation_frame_duration);} public static void Requestframedelay (Runnable Runnable, long delay) {Message message = new Message (); message.what = Msg_an Imate;message.obj = runnable;mhandler.sendmessagedelayed (message, delay);} private static class Animationhandler extends Handler {public void Handlemessage (Message m) {switch (m.what) {case Msg_ani Mate:if (m.obj! = null) {((Runnable) m.obj). Run (); Break;}}}} 
third, look at the last listen, call, realize mainactivity

Because the custom Switchbutton class is an inherited checkbox. So I still use this interface Oncheckedchangelistener. Use this interface for monitoring.

Package Com.switchbutton.activity;import Com.org.switchbtn.switchbutton;import Android.os.bundle;import Android.app.activity;import Android.widget.compoundbutton;import Android.widget.compoundbutton.oncheckedchangelistener;import Android.widget.toast;public class MainActivity Extends Activity implements Oncheckedchangelistener{private Switchbutton mmsgnotifyswitch;private Switchbutton Mmsgsoundswitch; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Initui ();} private void Initui () {Mmsgnotifyswitch = (Switchbutton) Findviewbyid (r.id.message_notify_switch); Mmsgsoundswitch = ( Switchbutton) Findviewbyid (R.id.message_sound_switch); Mmsgnotifyswitch.setoncheckedchangelistener (this); Mmsgsoundswitch.setoncheckedchangelistener (this);} @Overridepublic void OnCheckedChanged (Compoundbutton buttonview, Boolean isChecked) {switch (Buttonview.getid ()) {case R.id.message_notify_switch:if (isChecked) {Toast.maketext (this, "New Message Reminder open", Toast.length_short). Show ();} else {Toast.maketext (this, "new message reminder off", Toast.length_short). Show (); Break;case R.id.message_sound_switch:if (isChecked) {Toast.maketext (this, "sound alert Open", Toast.length_short). Show (); else {Toast.maketext (this, "sound alert Off", Toast.length_short). Show (); Break;default:break;}}}
Iv. enclosing the last XML

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools "android:layout_width=" match_parent "android:layout_height=" match_parent "> <Relat Ivelayout android:id= "@+id/sound_and_vibrate" android:layout_width= "Fill_parent" Android:layout_heigh t= "44.0dip" android:background= "@drawable/common_strip_setting_bottom" android:clickable= "false" Android Oid:focusable= "false" > <textview style= "@style/b4_font_white" android:layout_width= "WR Ap_content "android:layout_height=" Wrap_content "android:layout_centervertical=" true "and" roid:layout_marginleft= "12.0dip" android:duplicateparentstate= "true" android:gravity= "Center_vertica L "android:text=" @string/set_message_sound "/> <com.org.switchbtn.switchbutton android: Id= "@+id/message_sound_switch" andRoid:layout_width= "80dip" android:layout_height= "28dip" android:layout_alignparentright= "true"     Android:layout_centervertical= "true" android:layout_marginright= "8.0dip"/> </RelativeLayout> <relativelayout android:id= "@+id/pushsetting" android:layout_width= "Fill_parent" android:layou        t_height= "44.0dip" android:layout_alignparentleft= "true" android:layout_below= "@+id/sound_and_vibrate" android:background= "@drawable/common_strip_setting_top" android:clickable= "false" android:focusable= "false            "> <textview android:id=" @+id/encoding_style "style=" @style/b4_font_white " Android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" android:layout_centervertic Al= "true" android:layout_marginleft= "12.0dip" android:duplicateparentstate= "true" Android : gravity= "Center_verticaL "android:text=" @string/set_message_notify "/> <com.org.switchbtn.switchbutton Android            : id= "@+id/message_notify_switch" android:layout_width= "80dip" android:layout_height= "28dip" Android:layout_alignparentright= "true" android:layout_centervertical= "true" Android:layout_margin right= "8.0dip"/> </RelativeLayout></RelativeLayout>
It 's over here, welcome to the Exchange learning custom controls.

SOURCE Download: click

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Android Custom Switchbutton Switch controls

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.