Android Two-way sliding menu complete parsing, teach you how to achieve bidirectional sliding effects in one minute

Source: Internet
Author: User
Tags abs final integer sleep valid

I remember writing an article about the Android sliding menu a long time ago, in which a friend left a message in the comments, hoping I could help him change the sliding menu to a two-way slide. At that time did not want to spend too much time, a simple change to send him, the results did not expect a large number of friends have come to ask me to this two-way sliding menu code. Because this code is very hard to write, I made some friends really can't bear to continue to send down, so decided to write a special article to introduce better Android two-way sliding menu implementation method.

Before you start, talk about the implementation principle, in an activity layout needs to have three parts, one is the layout of the left menu, one is the layout of the right menu, one is the content layout. The left side of the menu is aligned to the left edge of the screen, the right menu is aligned to the right edge of the screen, and the content layout fills the entire screen, and is pressed over the left menu and the right-hand menu. When the user's finger slides to the right, the right menu is hidden, the left menu is displayed, and the location of the content layout is offset, allowing the left menu to unfold. In the same way, when the user slides to the left, the left menu is hidden, the right menu is displayed, and the location of the content layout is shifted, allowing the right-hand menu to unfold. The schematic diagram shows the following:

After introducing the principle, we begin to realize it. To create a new Android project, the project name is called Bidirslidinglayout. Then create our main bidirslidinglayout class, which is the core class that implements the bidirectional sliding menu function, as shown in the following code:

public class Bidirslidinglayout extends Relativelayout implements Ontouchlistener {/** * scrolling display and hide left cloth 
     When the board, the finger slides need to reach the speed.  
      
    * * public static final int snap_velocity = 200; 
     /** * A type of sliding state that indicates that no slippage has been made.  
      
    * * public static final int do_nothing = 0; 
     /** * One of the sliding states, indicating that the left menu is slipping.  
      
    * * public static final int show_left_menu = 1; 
     /** * One of the sliding states that is slipping out of the right menu.  
      
    * * public static final int show_right_menu = 2; 
     /** * One of the sliding states, indicating that the left menu is being hidden.  
      
    * * public static final int hide_left_menu = 3; 
     /** * One of the sliding states, indicating that the right menu is being hidden.  
      
    * * public static final int hide_right_menu = 4;  
      
    /** * Record the current sliding state/private int slidestate; 
     /** * Screen width value.  
      
    * * private int screenwidth; 
     /** * The maximum value that a user's finger can move before being judged to be scrolled.  
      
    * * private int touchslop; 
     /** * Record the horizontal axis when the finger is pressed. * * Private float Xdown;  
      
    /** * Record the ordinate when the finger is pressed.  
      
    * * Private float Ydown; 
     /** * Records the horizontal axis when the finger moves.  
      
    * * Private float xmove; 
     /** * Records the ordinate when the finger moves.  
      
    * * Private float ymove; 
     /** * Record the horizontal axis when the mobile phone is raised.  
      
    * * Private float xup; /** * The left menu is currently displayed or hidden. 
     This value is changed only when it is fully displayed or hidden, and this value is not valid during sliding.  
      
    * * Private Boolean isleftmenuvisible; /** * The right side of the menu is currently displayed or hidden. 
     This value is changed only when it is fully displayed or hidden, and this value is not valid during sliding.  
      
    * * Private Boolean isrightmenuvisible; 
     /** * is sliding.  
      
    * * Private Boolean issliding; 
     /** * left menu layout object.  
      
    * * Private View leftmenulayout; 
     /** * Right Menu Layout object.  
      
    * * Private View rightmenulayout; 
     /** * Content Layout object.  
      
    * * Private View contentlayout; 
     /** * Used to monitor view of sliding events.  
      
    * * Private View Mbindview; 
     /** * The parameters of the left menu layout.  
   * * Private marginlayoutparams leftmenulayoutparams;   
    /** * Right Menu layout parameters.  
      
    * * Private marginlayoutparams rightmenulayoutparams; 
     /** * The parameters of the content layout.  
      
    * * Private relativelayout.layoutparams contentlayoutparams; 
     /** * is used to calculate the speed at which fingers are sliding.  
      
    * * Private Velocitytracker Mvelocitytracker; 
     /** * Overrides the Bidirslidinglayout constructor, which gets the screen width and touchslop values.  * * @param context * @param attrs/Public bidirslidinglayout (context, AttributeSet attrs)  
        {Super (context, attrs);  
        WindowManager wm = (WindowManager) context.getsystemservice (Context.window_service);  
        ScreenWidth = Wm.getdefaultdisplay (). GetWidth ();  
    Touchslop = Viewconfiguration.get (context). Getscaledtouchslop (); 
     /** * Binds the view that listens for sliding events. 
     * * @param BindView * needs to bind to the View object.  
        */public void setscrollevent (View bindview) {mbindview = BindView; Mbindview.setontouchlistener (this); 
     /** * The interface is scrolled to the left menu interface and the scrolling speed is set to-30.  
    */public void Scrolltoleftmenu () {new Leftmenuscrolltask (). Execute (-30); 
     /** * The interface is scrolled to the right menu interface and the scrolling speed is set to-30.  
    */public void Scrolltorightmenu () {new Rightmenuscrolltask (). Execute (-30); 
     /** * To scroll the interface from the left menu to the content interface, scrolling speed set to 30.  
    */public void Scrolltocontentfromleftmenu () {new Leftmenuscrolltask (). Execute (30); 
     /** * Scrolls the interface from the right-hand menu to the content interface, with scrolling speed set to 30.  
    */public void Scrolltocontentfromrightmenu () {new Rightmenuscrolltask (). Execute (30); 
     The/** * left menu is fully displayed and this value is not valid during sliding. 
     * * @return the left menu full display returns True, otherwise returns false.  
    * * Public boolean isleftlayoutvisible () {return isleftmenuvisible; 
     The/** * Right menu is fully displayed and is not valid during sliding. 
     * * @return the right menu full display returns True, otherwise returns false. * * Public boolean isrightlayoutvisible () {return isrightmenuvisible; 
     /** * Reset the parameters of the left menu, the right menu, and the content layout in OnLayout. */@Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {super.onlayout (Chang  
        Ed, L, T, R, b);  
            if (changed) {//Get left Menu Layout Object leftmenulayout = Getchildat (0);  
            Leftmenulayoutparams = (marginlayoutparams) leftmenulayout.getlayoutparams ();  
            Gets the right menu layout object rightmenulayout = Getchildat (1);  
            Rightmenulayoutparams = (marginlayoutparams) rightmenulayout.getlayoutparams ();  
            Gets the content layout object contentlayout = Getchildat (2);  
            Contentlayoutparams = (relativelayout.layoutparams) contentlayout.getlayoutparams ();  
            Contentlayoutparams.width = ScreenWidth;  
        Contentlayout.setlayoutparams (Contentlayoutparams); @Override public boolean Ontouch (View V, motionevent EveNT) {Createvelocitytracker (event);  Switch (event.getaction ()) {case Motionevent.action_down://When the finger is pressed, the coordinates xdown when the record is pressed =  
            EVENT.GETRAWX ();  
            Ydown = Event.getrawy ();  
            Initializes the sliding state to do_nothing slidestate = do_nothing;  
        Break  
            Case MotionEvent.ACTION_MOVE:xMove = EVENT.GETRAWX ();  
            Ymove = Event.getrawy ();  
            When the finger moves, compare the coordinates of the pressed time to calculate the moving distance.  
            int Movedistancex = (int) (xmove-xdown);  
            int movedistancey = (int) (ymove-ydown);  
            Check the current sliding state checkslidestate (Movedistancex, Movedistancey); Determines how to offset the content layout switch (slidestate) {case Show_left_menu:contentlayo depending on the current sliding state  
                Utparams.rightmargin =-movedistancex;  
                Checkleftmenuborder ();  
                Contentlayout.setlayoutparams (Contentlayoutparams); BrEak  
                Case HIDE_LEFT_MENU:contentLayoutParams.rightMargin =-leftmenulayoutparams.width-movedistancex;  
                Checkleftmenuborder ();  
            Contentlayout.setlayoutparams (Contentlayoutparams);  
                Case SHOW_RIGHT_MENU:contentLayoutParams.leftMargin = Movedistancex;  
                Checkrightmenuborder ();  
                Contentlayout.setlayoutparams (Contentlayoutparams);  
            Break  
                Case HIDE_RIGHT_MENU:contentLayoutParams.leftMargin =-rightmenulayoutparams.width + Movedistancex;  
                Checkrightmenuborder ();  
            Contentlayout.setlayoutparams (Contentlayoutparams);  
            Default:break;  
        } break;  
            Case MotionEvent.ACTION_UP:xUp = EVENT.GETRAWX ();  
            int Updistancex = (int) (xup-xdown); if (issliding) {//Finger liftThe intention switch (slidestate) {case show_left_menu:if (SH) to determine the current gesture  
                    Ouldscrolltoleftmenu ()) {Scrolltoleftmenu ();  
                    else {scrolltocontentfromleftmenu ();  
                } break; Case Hide_left_menu:if (Shouldscrolltocontentfromleftmenu ()) {Scrolltoco  
                    Ntentfromleftmenu ();  
                    else {scrolltoleftmenu ();  
                } break; Case Show_right_menu:if (Shouldscrolltorightmenu ()) {Scrolltorightmenu ()  
                    ;  
                    else {scrolltocontentfromrightmenu ();  
                } break; Case Hide_right_menu:if (ShouldscrolltocontentfroMrightmenu ()) {Scrolltocontentfromrightmenu ();  
                    else {scrolltorightmenu ();  
                } break;  
                Default:break; } else if (Updistancex < touchslop && isleftmenuvisible) {//When the left menu is displayed, if the user clicks  
            Content section, then scroll directly to the Content interface Scrolltocontentfromleftmenu (); else if (Updistancex < touchslop && isrightmenuvisible) {//When the right-hand menu is displayed, if the user clicks on the Content section, scroll directly to the content  
            Interface Scrolltocontentfromrightmenu ();  
            } recyclevelocitytracker ();  
        Break The control does not get focus UNFOC if (v.isenabled ()) {if (issliding) {//is sliding)  
                Usbindview ();  
            return true;  
          } if (isleftmenuvisible | | isrightmenuvisible) {      Masks the events of the bound control off return True when the left or right layout is displayed;  
        return false;  
    return true; 
     /** * Determines the current user's sliding intent according to the distance the finger moves, and assigns the Slidestate value to the corresponding sliding state value. * * @param MOVEDISTANCEX * Horizontal Movement Distance * @param movedistancey * Vertical Movement distance *  
            /private void Checkslidestate (int movedistancex, int movedistancey) {if (isleftmenuvisible) {  
                if (!issliding && math.abs (Movedistancex) >= touchslop && Movedistancex < 0) {  
                Issliding = true;  
            Slidestate = Hide_left_menu; } else if (isrightmenuvisible) {if (!issliding && math.abs (Movedistancex) >= TOUCHSL  
                Op && Movedistancex > 0) {issliding = true;  
            Slidestate = Hide_right_menu; } else {if (!issliding && MatH.abs (Movedistancex) >= touchslop && Movedistancex > 0 && math.abs (movedistanc  
                EY) < Touchslop) {issliding = true;  
                Slidestate = Show_left_menu;  
                Contentlayoutparams.addrule (relativelayout.align_parent_left, 0);  
                Contentlayoutparams.addrule (Relativelayout.align_parent_right);  
                Contentlayout.setlayoutparams (Contentlayoutparams);  
                If the user wants to slide the left menu, the left menu is displayed, and the right menu hides leftmenulayout.setvisibility (view.visible);  
            Rightmenulayout.setvisibility (View.gone);
                    else if (!issliding && math.abs (Movedistancex) >= touchslop && Movedistancex < 0  
                && Math.Abs (Movedistancey) < Touchslop) {issliding = true;  
                Slidestate = Show_right_menu;  
 Contentlayoutparams.addrule (relativelayout.align_parent_right, 0);               Contentlayoutparams.addrule (Relativelayout.align_parent_left);  
                Contentlayout.setlayoutparams (Contentlayoutparams);  
                If the user wants to slide the right menu, the right menu is displayed, and the left menu hides rightmenulayout.setvisibility (view.visible);  
            Leftmenulayout.setvisibility (View.gone); 
     }}/** * checks the boundary value of the left menu during sliding to prevent the binding layout from slipping out of the screen. * * private void Checkleftmenuborder () {if (Contentlayoutparams.rightmargin > 0) {contentl  
        Ayoutparams.rightmargin = 0; else if (Contentlayoutparams.rightmargin <-leftmenulayoutparams.width) {Contentlayoutparams.rightmarg  
        in =-leftmenulayoutparams.width; 
     }/** * Checks the boundary value of the right menu during the slide to prevent the binding layout from slipping out of the screen. * * private void Checkrightmenuborder () {if (Contentlayoutparams.leftmargin > 0) {contentl  
        Ayoutparams.leftmargin = 0; else if (contentlayoutparAms.leftmargin <-rightmenulayoutparams.width) {Contentlayoutparams.leftmargin =-rightmenulayoutparams.  
        Width }/** * Determine if scrolling should be done to show the left menu. 
     If the finger moves more than 1/2 of the width of the left menu, or the finger moves faster than snap_velocity, * it should be scrolled to show the left menu. 
     * * @return returns False if the left menu should be shown to return true. * Private Boolean Shouldscrolltoleftmenu () {return xup-xdown > LEFTMENULAYOUTPARAMS.WIDTH/2 | | getS  
    Crollvelocity () > snap_velocity; /** * Determine if scrolling should be done to show the right menu. 
     If the finger moves more than 1/2 of the width of the right-hand menu, or the finger moves faster than snap_velocity, * it should be scrolled to show the right-hand menu. 
     * * @return returns False if the right menu should be shown to return true. * Private Boolean Shouldscrolltorightmenu () {return xdown-xup > RIGHTMENULAYOUTPARAMS.WIDTH/2 | | ge  
    Tscrollvelocity () > snap_velocity; 
     /** * Determines whether you should scroll from the left menu to the content layout, if your fingers move more than 1/2 of the width of the left menu, or if your fingers move faster than snap_velocity, * you should scroll from the left menu to the content layout. * * @return If you should scroll from the left menuReturns true to the content layout, otherwise returns false. * Private Boolean Shouldscrolltocontentfromleftmenu () {return xdown-xup > Leftmenulayoutparams.width /2 | |  
    Getscrollvelocity () > snap_velocity; 
     /** * Determines whether you should scroll from the right menu to the content layout, if your fingers move more than 1/2 of the width of the right menu, or if your fingers move faster than snap_velocity, * you should scroll from the right menu to the content layout. 
     * * @return returns FALSE if you should scroll from the right menu to the content layout to return true. * Private Boolean Shouldscrolltocontentfromrightmenu () {return xup-xdown > Rightmenulayoutparams.widt H/2 | |  
    Getscrollvelocity () > snap_velocity; 
     /** * Creates the Velocitytracker object and joins the touch event into the velocitytracker. * * @param event * Right layout listener control sliding event/private void Createvelocitytracker (Motionevent event  
        {if (Mvelocitytracker = = null) {Mvelocitytracker = Velocitytracker.obtain ();  
    } mvelocitytracker.addmovement (event); 
     /** * Gets the sliding speed of the finger on the binding layout.  
  *   * @return sliding speed, the number of pixels moved per second in units.  
        * * Private int getscrollvelocity () {mvelocitytracker.computecurrentvelocity (1000);  
        int velocity = (int) mvelocitytracker.getxvelocity ();  
    return math.abs (velocity); 
     /** * Reclaims Velocitytracker objects.  
        * * private void Recyclevelocitytracker () {mvelocitytracker.recycle ();  
    Mvelocitytracker = null; 
     /** * uses the control with the focus to lose focus when sliding.  
            * * private void Unfocusbindview () {if (Mbindview!= null) {mbindview.setpressed (false);  
            Mbindview.setfocusable (FALSE);  
        Mbindview.setfocusableintouchmode (FALSE); } class Leftmenuscrolltask extends Asynctask<integer, Integer, integer> {@Ove Rride protected integer doinbackground (integer ... speed) {int rightMargin = Contentlayoutparams.rig  
            Htmargin; Scroll through the interface according to the incoming speed, when scrolling arrivesBoundary value, jump out of the loop.  
                while (true) {RightMargin = RightMargin + speed[0];  
                    if (RightMargin <-leftmenulayoutparams.width) {rightMargin =-leftmenulayoutparams.width;  
                Break  
                    } if (RightMargin > 0) {rightMargin = 0;  
                Break  
                } publishprogress (RightMargin);  
                In order for the scrolling effect to occur, each loop causes the thread to sleep for a period of time, so the naked eye can see the scrolling animation.  
            Sleep (15);  
            } if (Speed[0] > 0) {isleftmenuvisible = false;  
            else {isleftmenuvisible = true;  
            } issliding = false;  
        return rightMargin; } @Override protected void Onprogressupdate (Integer ... rightMargin) {contentlayout  
            Params.rightmargin = rightmargin[0]; contentlayout.seTlayoutparams (Contentlayoutparams);  
        Unfocusbindview (); } @Override protected void OnPostExecute (Integer rightMargin) {Contentlayoutparams  
            . RightMargin = RightMargin;  
        Contentlayout.setlayoutparams (Contentlayoutparams); } class Rightmenuscrolltask extends Asynctask<integer, Integer, integer> {@Ov Erride protected integer doinbackground (integer ... speed) {int leftMargin = Contentlayoutparams.lef  
            Tmargin;  
            Scrolls the interface according to the incoming speed, and jumps out of the loop when scrolling reaches the boundary value.  
                while (true) {LeftMargin = LeftMargin + speed[0];  
                    if (LeftMargin <-rightmenulayoutparams.width) {leftMargin =-rightmenulayoutparams.width;  
                Break  
                    } if (LeftMargin > 0) {leftMargin = 0;  
                Break }  
                Publishprogress (LeftMargin);  
                In order for the scrolling effect to occur, each loop causes the thread to sleep for a period of time, so the naked eye can see the scrolling animation.  
            Sleep (15);  
            } if (Speed[0] > 0) {isrightmenuvisible = false;  
            else {isrightmenuvisible = true;  
            } issliding = false;  
        return leftMargin; } @Override protected void Onprogressupdate (Integer ... leftMargin) {CONTENTLAYOUTP  
            Arams.leftmargin = leftmargin[0];  
            Contentlayout.setlayoutparams (Contentlayoutparams);  
        Unfocusbindview (); } @Override protected void OnPostExecute (Integer leftMargin) {contentlayoutparams.  
            LeftMargin = LeftMargin;  
        Contentlayout.setlayoutparams (Contentlayoutparams); 
     }/** * Causes the current thread to sleep for the specified number of milliseconds. * * @param millis * Specifies how long the current thread sleeps toThe second is unit/private void sleep (long Millis) {try {thread.sleep (Millis);  
        catch (Interruptedexception e) {e.printstacktrace (); }  
    }  
}

Related Article

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.