Android Custom View slide switch supports left and right swipe for ListView

Source: Internet
Author: User


To make such a switch.

When the switch on the left, are gray, sliding to the right, when sliding halfway, change the color, turn green;

When the switch is on the right, the city is green, sliding to the left, when you swipe halfway, change the color and turn gray.

This involves sliding the maximum distance, and the distance you are now sliding. Compare this to change the color.


Import Android.content.context;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.canvas;import Android.graphics.paint;import Android.graphics.porterduff.mode;import Android.graphics.porterduffxfermode;import Android.graphics.rect;import Android.graphics.rectf;import Android.util.attributeset;import Android.util.log;import Android.view.motionevent;import Android.view.View; /** * Custom Switch button, * * */public class Pushslideswitchview extends view{/** switch bottom gray style picture */private Bitmap Mswitchbgunselet ed;/** switch bottom green style map */private Bitmap mswitchbgseleted;/** Switch Gray ball */private Bitmap mswitchballunseleted;/** Switch Green Colored ball */private Bitmap mswitchballseleted;private float mcurrentx = 0;/** switch switch state, default is on: True */private boolean MSWITC HOn = true;/** Switch maximum moving distance */private int mmovelength;/** Valid area for first press */private float MLASTX = 0;/** drawn target area size */privat e Rect mdest = null;  /** capture the size of the source picture *//** The offset of the Switch move */private int mmovedeltx = 0;/** Brush Tool*/private Paint mpaint = null;/** Switch Status Monitoring interface */private Onswitchchangedlistener Switchlistener = Null;private Boolean m Flag = false;/** The Enabled property is True */private boolean menabled = true;/** maximum transparency, which is opaque */private final int max_alpha = 255;/ * * Current transparency, mainly used here if the control's Enable property is set to False when semitransparent, that is, you can not click */private int malpha = max_alpha;/** Switch To determine whether you are dragging */private boolean MI sscrolled =false;public Pushslideswitchview (Context context) {This (context, null);} Public Pushslideswitchview (context context, AttributeSet Attrs) {This (context, attrs, 0);} Public Pushslideswitchview (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, defstyle); init ();} /** * Initializing related resources */public void init () {mswitchbgseleted = Bitmapfactory.decoderesource (Getresources (), R.drawable.push_ BUTTON_SELECTED_BG); mswitchbgunseleted = Bitmapfactory.decoderesource (Getresources (), R.drawable.push_button_ UNSELECTED_BG); mswitchballseleted = Bitmapfactory.decoderesource (Getresources (), R.drawable.push_button_ball_ selected); mswitchballunseleted = Bitmapfactory.decoderesource (Getresources (), r.drawable.push_button_ball_unselected); Mmovelength = Mswitchbgseleted.getwidth ()-mswitchballseleted.getwidth ();//plot Area size mdest = new Rect (0, 0, Mswitchbgseleted.getwidth (), Mswitchbgseleted.getheight ()), Mpaint = new Paint (); Mpaint.setantialias (true); Mpaint.setalpha (255); Mpaint.setxfermode (new Porterduffxfermode (mode.dst_in));} @Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {setmeasureddimension ( Mswitchbgseleted.getwidth (), Mswitchbgseleted.getheight ());} @Overrideprotected void OnDraw (canvas canvas) {Super.ondraw (canvas),/*SYSTEM.OUT.PRINTLN ("---onDraw ()---mmovedeltx  = "+ Mmovedeltx +" mswitchbgunseleted.getwidth () = "+ mswitchbgunseleted.getwidth () +" mswitchballseleted.getwidth () = " + mswitchballseleted.getwidth () + "mmovelength =" + mmovelength) */canvas.savelayeralpha (new RECTF (mDest), MAlpha, Canv As. Matrix_save_flag| Canvas.clip_save_flag | Canvas.has_alpha_layer_save_flag| Canvas.Full_color_layer_save_flag| Canvas.clip_to_layer_save_flag);//If it is closed if (!mswitchon) {if (Mmovedeltx > 0) {//to the right slide if (Mmovedeltx < mmovelength /2) {//sliding distance less than half canvas.drawbitmap (mswitchbgunseleted, 0, 0, NULL);//Grey background canvas.drawbitmap (mswitchballunseleted, MMOVEDELTX, 0, NULL); Gray button}else{//sliding distance greater than half Canvas.drawbitmap (mswitchbgseleted, 0, 0, NULL);//Green background canvas.drawbitmap (mswitchballseleted, MMOVEDELTX, 0, NULL); Green Button}}else{canvas.drawbitmap (mswitchbgunseleted, 0, 0, NULL);//gray background Canvas.drawbitmap (mswitchballunseleted, 0, 0, NULL); Gray button}}else{if (Mmovedeltx < 0) {//Swipe right with if (Math.Abs (MMOVEDELTX) < MMOVELENGTH/2) {//slide distance less than half canvas.drawbitmap ( mswitchbgseleted, 0, 0, NULL); Green background Canvas.drawbitmap (mswitchballseleted, Mswitchbgseleted.getwidth ()-mswitchballseleted.getwidth () + MMOVEDELTX, 0, NULL); Green Button}else{//sliding distance greater than half Canvas.drawbitmap (mswitchbgunseleted, 0, 0, NULL);//gray Background Canvas.drawbitmap ( Mswitchballunseleted, Mswitchbgseleted.getwidth ()-mswitchballseleted.getwidth () + MMOVEDELTX, 0, NULL); Gray button}}else{canvas.drawbitmap (mswitchbgseleted, 0, 0, NULL);//Green background canvas.drawbitmap (mswitchballseleted, Mmovelength, 0, NULL); Green button}}canvas.restore ();} @Overridepublic boolean ontouchevent (Motionevent event) {//TODO auto-generated method stub//If the Enabled property is set to True, The touch effect is only valid if (!menabled) {return true;} Switch (event.getaction ()) {Case MotionEvent.ACTION_DOWN:mLastX = Event.getx (); Break;case Motionevent.action_move: Mcurrentx = Event.getx (); mmovedeltx = (int) (MCURRENTX-MLASTX);//system.out.println ("===============" + MMoveDeltX); if (Mmovedeltx > 3) {//Set 3 This error distance, can better achieve click effect misscrolled = true;} If the switch is left on the right, or if the switch is on or off (this is not required) if (Mswitchon && mmovedeltx > 0) | | (!mswitchon && mmovedeltx < 0)) {mflag = True;mmovedeltx = 0;} if (Math.Abs (MMOVEDELTX) > mmovelength) {mmovedeltx = mmovedeltx > 0? mmovelength:-mmovelength;} Invalidate (); Break;case motionevent.action_up://If you have not slipped, consider a single click event if (!misscrolled) {Mmovedeltx = Mswitchon? Mmovelength:-mmovelEngth;mswitchon =!mswitchon;if (Switchlistener! = null) {Switchlistener.onswitchchange (this, Mswitchon);} Invalidate (); mmovedeltx = 0;break;} misscrolled = False;if (Math.Abs (MMOVEDELTX) > 0 && math.abs (MMOVEDELTX) < MMOVELENGTH/2) {mmovedeltx = 0; Invalidate ();} else if (Math.Abs (MMOVEDELTX) > mmovelength/2&& math.abs (MMOVEDELTX) <= mmovelength) {MMoveDeltX = MMoveDe LtX > 0? Mmovelength:-mmovelength;mswitchon =!mswitchon;if (Switchlistener! = null) {Switchlistener.onswitchchange (this, Mswitchon);} Invalidate (); mmovedeltx = 0;} else if (Mmovedeltx = = 0 && mflag) {//This is not required to be processed because the move is over Mmovedeltx = 0;mflag = false;} Default:break;} Invalidate (); return true;} /** * Set switch status listener * */public void Setonchangelistener (Onswitchchangedlistener listener) {Switchlistener = listener;} /** * Switch Switch Monitor interface * */public interface onswitchchangedlistener{public void Onswitchchange (Pushslideswitchview Switchvi EW, Boolean isChecked);} @Overridepublic VoiD setenabled (Boolean enabled) {//TODO auto-generated Method stubmenabled = Enabled;malpha = enabled? MAX_ALPHA:MAX_ALPHA/2; LOG.D ("Enabled", enabled?) "True": "false"); super.setenabled (enabled); Invalidate ();}    /** Automatic judgment switch to the opposite property: True-->false; false-->true */public void Toggle () {setchecked (!mswitchon);}        /** Sets the selected state (checked: True unchecked: false) */public void setchecked (Boolean checked) {Mswitchon = checked;    Invalidate (); }}



This is the kind of class that is available.

This can be referenced in the XML file:

<com.app.view.pushslideswitchview            android:id= "@+id/push_set_warm_switchview"            android:layout_width= " Wrap_content "            android:layout_height=" wrap_content "            android:layout_gravity=" center "            Android:layout_ marginright= "15dip"            android:enabled= "true"/>

Here is a list of four images to quote


In the Java code we listen to whether to turn on and off by setting Switchview.setonchangelistener ().


If it is a single use, use the above completely without problems.

But here is also a problem, if it is a ListView, if each item has one such switch, in the application permission settings may see such an operation scenario.

Previous use of other custom sliding switches will find that if you swipe up and down a few times, you will be confused, the left side will jump to the right, and some to the right will jump to the left. This also solves the problem.


The Java code is as follows

Package Com.example.compoundbuttonview;import Java.util.arraylist;import Java.util.hashmap;import java.util.List; Import Java.util.map;import android.app.activity;import Android.content.context;import Android.os.Bundle;import Android.view.layoutinflater;import Android.view.view;import Android.view.viewgroup;import Android.widget.baseadapter;import Android.widget.listview;import Android.widget.textview;import Com.example.compoundbuttonview.view.myslideswitchview;import com.example.compoundbuttonview.view.myslideswitchview.onswitchchangedlistener;/** */public class MainActivity2 Extends Activity {private ListView listview; list<map<string, object>> templistdata = new arraylist<map<string, object>> (); @ overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( R.LAYOUT.MAIN2); Initview (); for (int i = 0; i <; i++) {HashMap datamap = new hashmap<string, object> ();d Atamap. Put ("index", i+1);d atamap.put ("checked", I%2==0?true:false); Templistdata.add (Datamap);} Myadapter adapter = new Myadapter (mainactivity2.this); Listview.setadapter (adapter);} private void Initview () {listview = (ListView) Findviewbyid (R.id.listview1);} Class Myadapter extends Baseadapter {private Layoutinflater inflater = null;private Context context;public myadapter (Cont Ext context) {This.context = Context;inflater = Layoutinflater.from (context);} @Overridepublic int GetCount () {return templistdata.size ();} @Overridepublic Object getItem (int position) {return templistdata.get (position);} @Overridepublic long Getitemid (int position) {return position;} public void modifystates (int position) {} @Overridepublic view GetView (final int position, view Convertview, ViewGroup pare NT) {Viewholder holder;if (Convertview = = null) {Convertview = inflater.inflate (R.layout.main2_listview_item, NULL); Holder = new Viewholder (); holder.index = (TextView) Convertview.findviewbyid (R.id.item_index); holder. Slideswitchview = (Myslideswitchview) CONVERTVIEw.findviewbyid (R.id.item_switchview);//use tag to store data convertview.settag (holder);} else {holder = (Viewholder) Convertview.gettag ();} Holder.index.setText (Templistdata.get (position). Get ("index") + ""); holder. Slideswitchview.setchecked ((Boolean) templistdata.get (position). Get ("checked")); holder. Slideswitchview.setonchangelistener (New Onswitchchangedlistener () {@Overridepublic void Onswitchchange ( Myslideswitchview SwitchView, Boolean isChecked) {templistdata.get (position). Put ("checked", isChecked);}); return Convertview;}} Class Viewholder {public Myslideswitchview slideswitchview;public TextView Index;}}

The XML layout file is as follows:

Main2.xml

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"    xmlns:android1= "http// Schemas.android.com/apk/res/android "    android:layout_width=" match_parent "    android:layout_height=" Match_ Parent "    android:orientation=" vertical "    android:padding=" 1dip ">    <listview        android1:id=" @+ Id/listview1 "        android1:layout_width=" match_parent "        android1:layout_height=" wrap_content ">    </ListView></LinearLayout>

Item.xml

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"    xmlns:android1= "http// Schemas.android.com/apk/res/android "    android:layout_width=" match_parent "    android:layout_height=" Match_ Parent "    android:orientation=" vertical "    android:padding=" 1dip ">    <listview        android1:id=" @+ Id/listview1 "        android1:layout_width=" match_parent "        android1:layout_height=" wrap_content ">    </ Listview></linearlayout>

OK, because the code is all posted. There is no resources to download, the code has comments, look to understand, in fact, very useful.



Android Custom View slide switch supports left and right swipe for ListView

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.