Android Slide-Out menu Complete detailed example (improved version)

Source: Internet
Author: User

Mainactivity as follows:
Package Cc.cd;import Android.os.bundle;import Android.view.view;import android.view.view.onclicklistener;import Android.widget.adapterview;import Android.widget.adapterview.onitemclicklistener;import Android.widget.arrayadapter;import Android.widget.button;import Android.widget.listview;import Android.widget.toast;import Android.app.activity;import android.content.context;/** * Demo Description: * Encapsulates the side-slip menu used in Patience5 as a custom control for easy reuse * * This example differs in Patience5: * 1 Patience5 is a linearlayout layout, and the custom control inherits from Relativelayout * 2 in Patience5 is constantly changing the Menuview leftmargin and here is constantly changing the contentview of the * rightMargin. This is important to note when reading the code. * * Reference: * http://blog.csdn.net/guolin_blog/article/details/8744400 * Thank you very much */public class mainactivity    Extends Activity {private Context mcontext;private ListView Mcontentlistview;    Private Button Mcontentmenubutton;    Private Slidingmenurelativelayout mslidingmenurelativelayout;    private string [] listviewitems=new string [20]; Private Arrayadapter<string> MarrayaDapter; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.main); init ();} private void Init () {mcontext=this;mcontentlistview= (ListView) Findviewbyid (R.id.contentlistview); mcontentmenubutton= (Button) Findviewbyid (R.id.contentmenubutton); Mcontentmenubutton.setonclicklistener (new Onclicklistener () {@Overridepublic void OnClick (View view) {Boolean ismenuvisible= Mslidingmenurelativelayout.ismenuvisible (); if (ismenuvisible) {mslidingmenurelativelayout.scrolltocontent ();} else {mslidingmenurelativelayout.scrolltomenu ();}}); mslidingmenurelativelayout= (slidingmenurelativelayout) Findviewbyid (r.id.slidingmenurelativelayout);// Sliding events are bound on Contentlistview mslidingmenurelativelayout.setbindview (Mcontentlistview); Initlistviewdata (); Marrayadapter=new arrayadapter<string> (Mcontext, Android. R.layout.simple_list_item_1, ListViewItems); Mcontentlistview.setadapter (Marrayadapter); Mcontentlistview.setonitemclicklistener (New OnitemclicklistEner () {@Overridepublic void Onitemclick (adapterview<?> arg0, View arg1, int position, long arg3) {String item = Lis Tviewitems[position]; Toast.maketext (Mcontext, item, Toast.length_short). Show ();}}); private void Initlistviewdata () {String temp=null;for (int i = 0; i <; i++) {temp= "this is" +i;listviewitems[i]=temp; }}}


Slidingmenurelativelayout as follows:

Package Cc.cd;import Android.content.context;import Android.os.asynctask;import android.util.attributeset;import Android.view.motionevent;import Android.view.velocitytracker;import Android.view.view;import Android.view.viewconfiguration;import Android.view.windowmanager;import Android.widget.button;import Android.widget.relativelayout;import android.widget.toast;/** * Example Description: * 1 The custom control inherits from Relativelayout * 2 There are two parts Menuview and Contentview in the layout file. Because it's a relativelayout layout * so the two overlap.   * 3 Show and hide Menuview by changing the RightMargin value of Contentview * 4 Note that the Contentview alignment is set to Layout_alignparentright in the XML layout file * The Menuview alignment is set to Android:layout_alignparentleft. * So note the code: *//Set Contentview minimum and maximum rightmargin values * contentparamsminrightmargin=-mmenulayoutparams.width; * CONTENTPARAMSMAXRIGHTMARGIN=0; * This is quite ingenious. Because Contentview is right-aligned relative to the parent control. So in the original state * The value of his rightmargin is 0. When the finger is pressed to the right of the screen on the Contentview, it can continuously decrease its rightmargin, thus The Menuview *, which causes Contentview to move to the right side of the screen, is also visible. * So Contentview's maximum rightmargin value = 0, this is what we see when we enter the app: * Shows the Contentview, covers the Menuview. its rightmargin=0; aligns with the right side of the parent control. * When Contentview moves to the right of the screen, its rightmargin is gradually reduced until the absolute value of RightMargin * is the width of the menuview.    * * * Code Details: * 1 mmenulayoutparams and Mcontentlayoutparams are * marginlayoutparams types, because Menuview and Conentview's parent control *    is a custom slidingmenurelativelayout, not a common system xxxlayout * 2 swipe on the ListView on the finger and lift, sometimes the ListView item is pressed and has not been * Bounce. The cause of the phenomenon is temporarily unclear, but the Unfocusbindview () method can be used to make the ListView lose focus. The method is called two times in the example. You can observe the effect by annotating it. * There is still a small bug in the code for this. You need to continue to optimize later. */public class Slidingmenurelativelayout extends Relativelayout {private int screenwidth;private View Contentview; Private View Menuview;private View mbindview;private float xdown;private float xmove;private float xup;private float Ydown ;p rivate float ymove;private float yup;private Button mbutton;private Context mcontext;//is currently sliding private Boolean Isslidin g;//the maximum value that the user's finger can move before it is determined to scroll private int scaledtouchslop;//The flag bit that the menu is visible, which is not valid during the swipe process.//Only after the sliding end, This value is changed only when the menu is completely displayed or hidden private Boolean ismenuvisible = False;private INT Contentparamsmaxrightmargin = 0;private int contentparamsminrightmargin = 0;//Speed Tracking Private Velocitytracker mvelocitytracker;//threshold public static final int velocity_threshold = 200;//tagprivate final static String TAG = "Slidingmen Urelativelayout ";//Menu layout layoutparamsprivate marginlayoutparams mmenulayoutparams;// Content layout Layoutparamsprivate marginlayoutparams mcontentlayoutparams;public slidingmenurelativelayout (Context Context) {super (context);} Public Slidingmenurelativelayout (context context, AttributeSet Attrs) {Super (context, attrs); init (context);} Public Slidingmenurelativelayout (context context, AttributeSet Attrs,int Defstyle) {Super (context, attrs, Defstyle);} @Overrideprotected void OnLayout (Boolean changed, int l, int t, int r, int b) {super.onlayout (changed, L, T, R, b); if (cha nged) {//Initialize Contentviewcontentview = Getchildat (1); mcontentlayoutparams = (marginlayoutparams) Contentview.getlayoutparams ();//sets the width of the contentview to the width of the screen mcontentlayoutparams.width = Screenwidth;contEntview.setlayoutparams (mcontentlayoutparams);//Initialize Menuviewmenuview = Getchildat (0); mmenulayoutparams = ( Marginlayoutparams) Menuview.getlayoutparams ();//set minimum and maximum rightmargin values for contentview. Contentparamsminrightmargin =- Mmenulayoutparams.width;contentparamsmaxrightmargin = 0;mbutton = (Button) Menuview.findviewbyid (R.id.menuButton); Mbutton.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (view view) {Toast.maketext (Mcontext, " Hello ", Toast.length_short). Show ();}});}} private void init (context context) {Mcontext = context;//get screen width windowmanager WindowManager = (windowmanager) mcontext.ge Tsystemservice (context.window_service); screenwidth = Windowmanager.getdefaultdisplay (). GetWidth ();// Gets scaledtouchslopscaledtouchslop = Viewconfiguration.get (context). Getscaledtouchslop ();} /** * The view registered to handle the touch event in the change example handles the ListView touch to show and hide the Menuview. * Other controls */public void Setbindview (View bindview) {Mbindview = Bindview;mbindview.setontouchlistener) can be set according to requirements in actual development ( New Touchlistenerimpl());} Causes BindView to lose focus public void Unfocusbindview () {if (Mbindview! = null) {mbindview.setpressed (false); Mbindview.setfocusable (false); Mbindview.setfocusableintouchmode (false);}} Private class Touchlistenerimpl implements Ontouchlistener {@Overridepublic Boolean onTouch (View V, motionevent event) {/ /start Speed tracking Startvelocitytracker (event), switch (Event.getaction ()) {Case MotionEvent.ACTION_DOWN:xDown = EVENT.GETRAWX () ; ydown = Event.getrawy (); Break;case MotionEvent.ACTION_MOVE:xMove = Event.getrawx (); ymove = Event.getrawy (); int Distancex = (int) (xmove-xdown); int distancey = (int) (ymove-ydown);//finger slides to the right of the screen, Distancex to positive if (!ismenuvisible&&am P Distancex >= scaledtouchslop&& (issliding | | Math.Abs (Distancey) <= scaledtouchslop)) {issliding = True;mcontentlayoutparams.rightmargin =-distanceX;// Handle out-of-bounds conditions if (Mcontentlayoutparams.rightmargin < contentparamsminrightmargin) {Mcontentlayoutparams.rightmargin = Contentparamsminrightmargin;} Set the Layoutparamscontentvie of ContentviewW.setlayoutparams (mcontentlayoutparams);} Swipe your finger to the left of the screen, Distancex negative if (ismenuvisible &&-distancex >= scaledtouchslop) {issliding = true; Mcontentlayoutparams.rightmargin = contentparamsminrightmargin-distancex;//handles out-of-bounds conditions if ( Mcontentlayoutparams.rightmargin > Contentparamsmaxrightmargin) {mcontentlayoutparams.rightmargin = Contentparamsmaxrightmargin;} Set the Contentview layoutparamscontentview.setlayoutparams (mcontentlayoutparams);} Break;case MotionEvent.ACTION_UP:xUp = EVENT.GETRAWX (), int updistancex = (int) (Xup-xdown), if (issliding) {//Judgment gesture intent to display M Enuif (Wanttoshowmenu ()) {//Determines whether to show Menuif (Shouldscrolltomenu ()) {Scrolltomenu ();} else {scrolltocontent ();}} Determine the gesture intent to show Contentif (Wanttoshowcontent ()) {//To determine if the display is Contentif (Shouldscrolltocontent ()) {scrolltocontent ();} else { Scrolltomenu ();}}} else {//When the menu interface is fully displayed, click only the visible Contentview to display it fully if (Updistancex < scaledtouchslop && ismenuvisible) { Scrolltocontent ();}} Stop speed tracking Stopvelocitytracker (); break;default:break;} /** * The If...else is judged after the down,move,up has been processed.  * 1 returns False if it is not in a sliding state. Otherwise the ListView cannot slide and its item cannot be clicked. * 2 If you are sliding, let the ListView lose focus. */if (!issliding) {return false;} else {Unfocusbindview ();} return true;}} /** * Determines whether the current gesture wants to display menu menus * Judging Condition: * 1 lift coordinates greater than press coordinates * 2 menu itself is not visible */private Boolean wanttoshowmenu () {return (Xup-xdown & Gt 0) && (!ismenuvisible));} /** * Determine if the menu should be fully displayed * Judging condition: The sliding distance is greater than one-second of the menu or the sliding speed is greater than the speed threshold Velocity_threshold */private boolean shouldscrolltome Nu () {return (Xup-xdown > MMENULAYOUTPARAMS.WIDTH/2) | | (Getscrollvelocity () > Velocity_threshold));} /** * Scroll the screen to menu. The menu will be displayed in full. */public void Scrolltomenu () {new Scrollasynctask (). Execute (-30);} /** * Determines whether the current gesture wants to display the menu content * Judging Condition: * 1 lift coordinates less than press coordinates * 2 menu itself visible */private boolean wanttoshowcontent () {return (xup-xdo WN < 0) && (ismenuvisible));} /** * Determine if the content should be fully displayed * Judging condition: The sliding distance is greater than one-second of the menu or the sliding speed is greater than the speed threshold Velocity_threshold */private boolean shouldscrollt Ocontent () {return (Xdown-xup > MmenulaYOUTPARAMS.WIDTH/2) | | (Getscrollvelocity () > Velocity_threshold));} /** * Scrolls the screen to content. The content will be displayed in full */public void Scrolltocontent () {new Scrollasynctask (). Execute (30);} public Boolean ismenuvisible () {return ismenuvisible;} /** * Start speed tracking */private void Startvelocitytracker (Motionevent event) {if (Mvelocitytracker = = null) {Mvelocitytracker = Vel Ocitytracker.obtain ();} Mvelocitytracker.addmovement (event);} /** * Gets the finger sliding speed in the x direction of the content */private int getscrollvelocity () {// Sets the Velocitytracker unit. 1000 indicates the pixel mvelocitytracker.computecurrentvelocity (1000) that is moving within 1 seconds, and/or gets the pixel value in the x direction in 1 seconds int xvelocity = (int) mvelocitytracker.getxvelocity (); return Math.Abs (xvelocity);} /** * Stop speed trace */private void Stopvelocitytracker () {if (Mvelocitytracker! = null) {mvelocitytracker.recycle (); Mvelocitytracker = null;}} /** * Use asynchronous tasks to constantly modify RightMargin in Contentview layoutparams to achieve Contentview View movement */private class Scrollasynctask extends Asynctask<integer, Integer, integer> {@Overrideprotected integer doinbackground (IntEger. Speed) {int contentlayoutparamsrightmargin = Mcontentlayoutparams.rightmargin;while (True) {// Speedcontentlayoutparamsrightmargin of each change = Contentlayoutparamsrightmargin + speed[0];//If out of bounds, the processing is out of bounds and the loop jumps out if ( Contentlayoutparamsrightmargin > Contentparamsmaxrightmargin) {contentlayoutparamsrightmargin = Contentparamsmaxrightmargin;break;} If out of bounds, the processing is out of bounds and the loop jumps out if (Contentlayoutparamsrightmargin < Contentparamsminrightmargin) { Contentlayoutparamsrightmargin = Contentparamsminrightmargin;break;} Notification Progress update publishprogress (contentlayoutparamsrightmargin);//thread Sleep 15 milliseconds, easy to reflect the scrolling effect try {thread.sleep (+);} catch ( Exception e) {}}//sets the flag bit Ismenuvisibleif (Speed[0] > 0) {ismenuvisible = false;} else {ismenuvisible = true;} According to the speed of the slide issliding = False;return Contentlayoutparamsrightmargin;} @Overrideprotected void Onprogressupdate (Integer ... rightMargin) {super.onprogressupdate (rightMargin); Mcontentlayoutparams.rightmargin = Rightmargin[0];contentview.setlayoutparams (mcontentlayoutparams); Unfocusbindview ();} @Overrideprotected void OnPostExecute (Integer rightMargin) {super.onpostexecute (rightMargin); Mcontentlayoutparams.rightmargin = Rightmargin;contentview.setlayoutparams (Mcontentlayoutparams);}}

Main.xml as follows:

<cc.cd.slidingmenurelativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http ://schemas.android.com/tools "android:id=" @+id/slidingmenurelativelayout "android:layout_width=" Match_parent "and roid:layout_height= "Match_parent" > <relativelayout android:id= "@+id/menurelativelayout" Android:la Yout_width= "270dip" android:layout_height= "Match_parent" android:layout_alignparentleft= "true" Androi d:background= "#00ccff" > <textview android:id= "@+id/menutextview" android:layout_width= "            Wrap_content "android:layout_height=" Wrap_content "android:layout_centerhorizontal=" true " Android:text= "This is Menu" android:textcolor= "#000000" android:textsize= "25sp"/> <bu Tton android:id= "@+id/menubutton" android:layout_width= "Wrap_content" Android:layout_hei Ght= "Wrap_content" aNdroid:layout_centerinparent= "True" android:text= "click here" android:textcolor= "#000000" Android:textsize= "25sp"/> </RelativeLayout> <linearlayout android:id= "@+id/contentli Nearlayout "android:layout_width=" 320dip "android:layout_height=" Match_parent "Android:layout_alignpa            Rentright= "true" android:background= "#e9e9e9" android:orientation= "vertical" > <button Android:id= "@+id/contentmenubutton" android:layout_width= "wrap_content" android:layout_height= "WR            Ap_content "android:text=" menu "/> <listview android:id=" @+id/contentlistview " Android:layout_width= "Fill_parent" android:layout_height= "fill_parent" android:cachecolorhint= "#0 0000000 "/> </LinearLayout></cc.cd.SlidingMenuRelativeLayout>


Android Slide-Out menu Complete detailed example (improved version)

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.