Android-Implementation of the simplest Custom button in history, android Switch

Source: Internet
Author: User

Android-Implementation of the simplest Custom button in history, android Switch

Reprinted please indicate the source: http://blog.csdn.net/l1028386804/article/details/48102871

Most of the time, we have such an effect in many Android and IOS apps. There is a button, and we click it to slide it, "On" will be displayed, and "off" will be displayed. This is the switch button. For example, many functions of the setting function of Android phones are implemented by the switch button, how are these buttons implemented? Next, let's implement this function together.

I. Principles

We place A background image A in A certain area of the interface. This image is "Open" and "off" while "B" is placed on this image, figure B is about half of Figure A. It can overwrite the "on" or "Off" of Figure A. When we click the image with our fingers, figure B slides over figure, overwrite "on" or "Off" to enable the switch button.

II. Implementation 1. Custom View class MyToggle

This class inherits from the View class and implements the OnTouchListener interface at the same time. This class provides many functions. Let's look at this class.

1) attribute Field

This class defines a lot of attribute fields. For the specific meaning of each attribute field, see the code comment.

The specific implementation code is as follows:

// The private Bitmap bkgSwitchOn of the background image on which the switch is enabled; // The private Bitmap bkgSwitchOff of the background image on which the switch is disabled; // The private Bitmap btnSlip of the rolling image on which the switch is enabled; // whether the current switch is in the Enabled state private boolean toggleStateOn; // The Listener event private OnToggleStateListener toggleStateListener; // record the switch · Current State private boolean isToggleStateListenerOn; // The x coordinate private float proX when the finger presses the screen; // The current x coordinate private float currentX when the finger slides; // whether the sliding state is private boolean isSlipping; // record the last switch State private boolean proToggleState = true; // The rectangular private Rect rect_on when the switch is on; // The rectangular private Rect rect_off when the switch is off;

2) override the construction method of the View class

The operation we complete in the constructor is to call the init () method we have created.

The specific implementation code is as follows:

public MyToggle(Context context) {super(context);init(context);}public MyToggle(Context context, AttributeSet attrs) {super(context, attrs);init(context);}

3) Create the init Method

The Operation implemented in this method is to set the touch event.

The specific implementation code is as follows:

// Initialization method private void init (Context context) {setOnTouchListener (this );}

4) The callback method of the finger touch event is onTouch.

This method is the Android automatic callback method when the finger is used to operate the mobile phone screen. In this method, we listen to the pressing, moving, and lifting events of the finger, record the current X coordinate of the finger to determine the movement direction of Image B, so that image B moves on image A to enable and disable the button.

The specific implementation code is as follows:

@ Overridepublic boolean onTouch (View v, MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: // records the x coordinate proX = event when the finger is pressed. getX (); currentX = proX; // set the slide ID to trueisSlipping = true; break; case MotionEvent. ACTION_MOVE: // record the current x coordinate currentX = event during finger sliding. getX (); break; case MotionEvent. ACTION_UP: // when the finger is lifted, set whether to slide the flag to falseisSlipping = false; // if (currentX <bkgSwitchOn. getWidth ()/2) {t OggleStateOn = false;} else {// toggleStateOn = true;} // If the listener is enabled and the status of the listener is changed, use this Code if (isToggleStateListenerOn & toggleStateOn! = ProToggleState) {proToggleState = toggleStateOn; toggleStateListener. onToggleState (toggleStateOn);} break;} invalidate (); // re-paint return true ;}

5) interface repainting method onDraw

This method mainly implements the interface re-painting operation.

As long as the idea is:

Background image:

When the current finger slides the X coordinate currentX greater than the width of Figure A, the button background is enabled;

When the current finger slides the X coordinate currentX less than the width of Figure A, the button background is disabled;

Record the X coordinates of Slider B:

B sliding:

If the current finger slide X coordinate currentX is greater than the width of background image A, then coordinate B is the width of image A minus the width of Image B.

If the current finger slides the X coordinate currentX less than the width of background image A, the B coordinate is the current X coordinate currentX minus half of the width of the slider.

B static:

When the button is in the "on" status, the coordinate B is the leftmost X coordinate of the "on" status.

When the button is in the off state, the coordinate B is the leftmost X coordinate of the off state.

The specific implementation code is as follows:

@ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas); // used to record the position of the sliding block. int left_slip = 0; Matrix matrix = new Matrix (); Paint paint = new Paint (); if (currentX <bkgSwitchOn. getWidth ()/2) {// draw the canvas of the background image when the switch is off. drawBitmap (bkgSwitchOff, matrix, paint);} else {// draw the canvas where the switch status is enabled. drawBitmap (bkgSwitchOn, matrix, paint);} if (isSlipping) {// whether the switch is in the sliding state // whether the sliding block exceeds the width of the entire sliding button if (currentX> bkgSwitchOn. getWidth () {// specify the position of the slider left_slip = bkgSwitchOn. getWidth ()-btnSlip. getWidth ();} else {// set the position of the current slider left_slip = (int) (currentX-btnSlip. getWidth ()/2) ;}} else {// whether the switch is in the non-slip state if (toggleStateOn) {left_slip = rect_on.left;} else {left_slip = rect_off.left ;}} if (left_slip <0) {left_slip = 0;} else if (left_slip> bkgSwitchOn. getWidth ()-btnSlip. getWidth () {left_slip = bkgSwitchOn. getWidth ()-btnSlip. getWidth ();} // draw the image canvas. drawBitmap (btnSlip, left_slip, 0, paint );}

6) Calculate the switch width and height

Here I overwrite onMeasure to calculate the width and height of the switch.

The specific implementation code is as follows:

// Calculate the switch width and height @ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension (bkgSwitchOn. getWidth (), bkgSwitchOn. getHeight ());}

7) set image Resource Information

This method is mainly used for external calls to provide image resources for this class.

The Code is as follows:

/*** Set image Resource Information ** @ param listener * @ param btn_Slip */public void setImageRes (int duration, int bkgSwitch_off, int btn_Slip) {bkgSwitchOn = BitmapFactory. decodeResource (getResources (), bkgSwitch_on); bkgSwitchOff = BitmapFactory. decodeResource (getResources (), bkgSwitch_off); btnSlip = BitmapFactory. decodeResource (getResources (), btn_Slip); rect_on = new Rect (bkgSwitchOn. getWidth ()-btnSlip. getWidth (), 0, bkgSwitchOn. getWidth (), btnSlip. getHeight (); rect_off = new Rect (0, 0, btnSlip. getWidth (), btnSlip. getHeight ());}

8) set the status of the switch button

By passing a boolean state, we record this state identifier in this method.

The specific implementation code is as follows:

/*** Set the status of the switch button * @ param state */public void setToggleState (boolean state) {toggleStateOn = state ;}

9) custom Switch Status listener

In this class, I defined an OnToggleStateListener interface for the listener of the switch status, which contains an onToggleState method to perform the listener of the status change of the button.

The Code is as follows:

/*** Custom Switch Status listener * @ author liuyazhuang **/interface OnToggleStateListener {abstract void onToggleState (boolean state );}

10) set the listener

Create the listener method, pass an OnToggleStateListener listener object, create an OnToggleStateListener object from the outside, and pass the OnToggleStateListener object. We only need to record the OnToggleStateListener object passed from the outside, when we call the onToggleState method in the OnToggleStateListener interface, the onToggleState method in the OnToggleStateListener implementation class is implemented.

The Code is as follows:

// Set the listener to truepublic void setOnToggleStateListener (OnToggleStateListener listener) {toggleStateListener = listener; isToggleStateListenerOn = true ;}

11) Complete MyToggle code is as follows:

Package com. lyz. slip. toggle; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapFactory; import android. graphics. canvas; import android. graphics. matrix; import android. graphics. paint; import android. graphics. rect; import android. util. attributeSet; import android. view. motionEvent; import android. view. view; import android. view. view. onTouchListener;/*** custom switch class * @ autho R liuyazhuang **/public class MyToggle extends View implements OnTouchListener {// background image with the switch enabled private Bitmap bkgSwitchOn; // The background image with the switch disabled private Bitmap bkgSwitchOff; // private Bitmap btnSlip; // whether the current switch is in the Enabled state: private boolean toggleStateOn; // The Listener event private OnToggleStateListener toggleStateListener; // record switch · Current State private boolean isToggleStateListenerOn; // The x coordinate private float proX when the finger presses the screen; // The current x coordinate private Float currentX; // whether it is in the sliding State private boolean isSlipping; // record the status of the last switch private boolean proToggleState = true; // The rectangular private Rect rect_on when the switch is enabled; // private Rect rect_off when the switch is off; public MyToggle (Context context) {super (context); init (context);} public MyToggle (Context context, AttributeSet attrs) {super (context, attrs); init (context) ;}// initialization method private void init (Context context) {setOnTouchListener (this) ;}@ Overridepu Blic boolean onTouch (View v, MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: // records the x coordinate proX = event when the finger is pressed. getX (); currentX = proX; // set the slide ID to trueisSlipping = true; break; case MotionEvent. ACTION_MOVE: // record the current x coordinate currentX = event during finger sliding. getX (); break; case MotionEvent. ACTION_UP: // when the finger is lifted, set whether to slide the flag to falseisSlipping = false; // if (currentX <bkgSwitchOn. getWidth ()/2) {toggleState On = false;} else {// toggleStateOn = true;} // If the listener is enabled and the status of the listener is changed, use this Code if (isToggleStateListenerOn & toggleStateOn! = ProToggleState) {proToggleState = toggleStateOn; toggleStateListener. onToggleState (toggleStateOn);} break;} invalidate (); // re-paint return true;} @ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas); // used to record the position of the sliding block. int left_slip = 0; Matrix matrix = new Matrix (); Paint paint = new Paint (); if (currentX <bkgSwitchOn. getWidth ()/2) {// draw the canvas of the background image when the switch is off. drawBitmap (bkgSwitchOff, matrix, paint);} else {// draw the canvas where the switch status is enabled. drawBitmap (bkgSwitchOn, matrix, paint);} if (isSlipping) {// whether the switch is in the sliding state // whether the sliding block exceeds the width of the entire sliding button if (currentX> bkgSwitchOn. getWidth () {// specify the position of the slider left_slip = bkgSwitchOn. getWidth ()-btnSlip. getWidth ();} else {// set the position of the current slider left_slip = (int) (currentX-btnSlip. getWidth ()/2) ;}} else {// whether the switch is in the non-slip state if (toggleStateOn) {left_slip = rect_on.left;} else {left_slip = rect_off.left ;}} if (left_slip <0) {left_slip = 0;} else if (left_slip> bkgSwitchOn. getWidth ()-btnSlip. getWidth () {left_slip = bkgSwitchOn. getWidth ()-btnSlip. getWidth ();} // draw the image canvas. drawBitmap (btnSlip, left_slip, 0, paint);} // calculate the width and height of the switch @ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {Scheme (bkgSwitchOn. getWidth (), bkgSwitchOn. getHeight ();}/*** sets image resource information * @ param listener * @ param bkgSwitch_off * @ param btn_Slip */public void setImageRes (int bkgSwitch_on, int bkgSwitch_off, int btn_Slip) {bkgSwitchOn = BitmapFactory. decodeResource (getResources (), bkgSwitch_on); bkgSwitchOff = BitmapFactory. decodeResource (getResources (), bkgSwitch_off); btnSlip = BitmapFactory. decodeResource (getResources (), btn_Slip); rect_on = new Rect (bkgSwitchOn. getWidth ()-btnSlip. getWidth (), 0, bkgSwitchOn. getWidth (), btnSlip. getHeight (); rect_off = new Rect (0, 0, btnSlip. getWidth (), btnSlip. getHeight ();}/*** set the status of the switch button * @ param state */public void setToggleState (boolean state) {toggleStateOn = state ;} /*** custom Switch Status listener * @ author liuyazhuang **/interface OnToggleStateListener {abstract void onToggleState (boolean state );} // set the listener and set the listener to truepublic void setOnToggleStateListener (OnToggleStateListener listener) {toggleStateListener = listener; isToggleStateListenerOn = true ;}}

2. MainActivity

The implementation of this class is very simple. The main function is to load the interface layout, initialize the interface control, and call the methods in the MyToggle class to implement the switch effect of the button.
The Code is as follows:

Package com. lyz. slip. toggle; import android. app. activity; import android. OS. bundle; import android. widget. toast; import com. lyz. slip. toggle. myToggle. onToggleStateListener;/*** main entry of the Program * @ author liuyazhuang **/public class MainActivity extends Activity {// custom switch object private MyToggle toggle; @ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); toggle = (MyToggle) findViewById (R. id. toggle); // set toggle to display the image. setImageRes (R. drawable. bkg_switch, R. drawable. bkg_switch, R. drawable. btn_slip); // set the default status of the toggle switch to true. setToggleState (true); // sets toggle for the toggle listener. setOnToggleStateListener (new OnToggleStateListener () {@ Overridepublic void onToggleState (boolean state) {// TODO Auto-generated method stubif (state) {Toast. makeText (getApplicationContext (), "enabled", 0 ). show ();} else {Toast. makeText (getApplicationContext (), "switch off", 0 ). show ();}}});}}

3. layout file activity_main.xml

Here I reference the custom View class MyToggle.

The Code is as follows:

<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" >    <com.lyz.slip.toggle.MyToggle        android:id="@+id/toggle"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"/></RelativeLayout>

4. AndroidManifest. xml

The Code is as follows:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.lyz.slip.toggle"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="10"        android:targetSdkVersion="18" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.lyz.slip.toggle.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

Iii. Running Effect



4. Tips

You can go to the links

In this example, for the purpose of writing some text directly in the layout file and related classes, you need to write these words in the real project. in xml files, reference these resources externally. Remember, this is the most basic development knowledge and specification for an Android programmer. I am writing these resources in the class and layout files for convenience.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.