Android up and down menu bidirectional sliding implementation

Source: Internet
Author: User

This is to study the online big God two-way swipe left and right to achieve the two-way sliding effects, interested friends can look at the following code, comments are detailed, the principle is based on the direction of the finger swipe, to the top and bottom two layout to show and hide. The Ontouch method is used mainly to get the distance of sliding to offset.


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.view.view.ontouchlistener;import Android.widget.relativelayout;public class Upanddownslidinglayout extends Relativelayout implements ontouchlistener{ /** * Scroll to show and hide the upper side of the layout when the finger slide needs to be reached speed. */public static final int snap_velocity = 200;/** * One of the sliding states, indicating that no slippage has been made. */public static final int do_nothing = 0;/** * One of the sliding states, indicating that the upper-side menu is being slid out. */public static final int show_up_menu = 1;/** * One of the sliding states that is slipping out of the lower side menu. */public static final int show_down_menu = 2;/** * One of the sliding states, indicating that the upper-side menu is being hidden. */public static final int hide_up_menu = 3;/** * One of the sliding states, indicating that the lower side menu is being hidden. */public static final int hide_down_menu = 4;/** * Records the current sliding state */private int slidestate;/** * Screen width value. */private int screenwidth;private int screenheight;/** * The maximum value that the user's finger can move before being judged to be scrolled. */private int TOUCHSLop;/** * Record the horizontal axis of the finger when pressed. */private float xdown;/** * Records the ordinate when the finger is pressed. */private float ydown;/** * Records the horizontal axis of the finger when moving. */private float xmove;/** * Records the ordinate when the finger moves. */private float ymove;/** * Records the ordinate when the phone is lifted. */private Float yup;/** * The upper-side 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 the slide. */private Boolean isupmenuvisible;/** * The lower-side 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 the slide. */private Boolean isdownmenuvisible;/** * is sliding. */private Boolean issliding;/** * upper-side Menu Layout object. */private View upmenulayout;/** * Lower side menu Layout object. */private View downmenulayout;/** * Content Layout object. */private View contentlayout;/** * is used to monitor the view of a sliding event. */private View mbindview;/** * parameters for the upper side menu layout. */private marginlayoutparams upmenulayoutparams;/** * The parameters of the lower side menu layout. */private marginlayoutparams downmenulayoutparams;/** * The parameters of the content layout. */private relativelayout.layoutparams contentlayoutparams;/** * is used to calculate the speed of finger slippage. */private velocitytracker mvelocitytracker;public upanddownslidinglayout (context context, AttributeSet Attrs) {super ( context, attrs); WindowManager wm = (WindowManager) context.getsystEmservice (context.window_service); screenwidth = Wm.getdefaultdisplay (). getwidth (); screenheight = Wm.getdefaultdisplay (). GetHeight (); touchslop = Viewconfiguration.get (context). Getscaledtouchslop (); /** * A view that is bound to listen for sliding events. * * @param BindView * The View object that needs to be bound. */public void Setscrollevent (View bindview) {Mbindview = Bindview;mbindview.setontouchlistener (this);} @Overridepublic boolean OnTouch (View V, motionevent event) {//TODO auto-generated method Stubcreatevelocitytracker ( event), switch (Event.getaction ()) {case motionevent.action_down://finger pressed, record the coordinates when pressed Xdown = Event.getrawx (); Ydown = Event.getrawy ();//Initialize the sliding state to Do_nothingslidestate = do_nothing;break;case MotionEvent.ACTION_MOVE:xMove = EVENT.GETRAWX (); ymove = Event.getrawy (); int movedistancex = (int) (xmove-xdown); int movedistancey = (int) (Ymove-ydown );//Check the current sliding state checkslidestate (Movedistancex, Movedistancey); switch (slidestate) {case Show_up_menu: Contentlayoutparams.bottommargin =-movedistancey;checkupmenuborder (); contentlAyout.setlayoutparams (contentlayoutparams); Break;case HIDE_UP_MENU:contentLayoutParams.bottomMargin =- Upmenulayoutparams.height-movedistancey;checkupmenuborder (); Contentlayout.setlayoutparams (ContentLayoutParams) ; Case SHOW_DOWN_MENU:contentLayoutParams.topMargin = Movedistancey;checkdownmenuborder (); Contentlayout.setlayoutparams (contentlayoutparams); Break;case HIDE_DOWN_MENU:contentLayoutParams.topMargin =- Downmenulayoutparams.height + Movedistancey;checkdownmenuborder (); Contentlayout.setlayoutparams ( Contentlayoutparams);d Efault:break;}       Break Case MotionEvent.ACTION_UP:yUp = Event.getrawy (), int updistancey = (int) (Yup-ydown), if (issliding) {//When the finger is lifted, to determine the meaning of the current gesture Figure switch (slidestate) {case show_up_menu:if (Shouldscrolltoupmenu ()) {Scrolltoupmenu ();} else { Scrolltocontentfromupmenu ();} Break;case hide_up_menu:if (Shouldscrolltocontentfromupmenu ()) {Scrolltocontentfromupmenu ();} else {ScrollToUpMenu ( );} Break;case show_down_menu:if (Shouldscrolltodownmenu ()) {Scrolltodownmenu ();}else {scrolltocontentfromdownmenu ();} Break;case hide_down_menu:if (Shouldscrolltocontentfromdownmenu ()) {Scrolltocontentfromdownmenu ();} else { Scrolltodownmenu ();} Break;default:break;}} else if (Updistancey < touchslop && isupmenuvisible) {//when the upper-side menu is displayed, if the user clicks on the Content section, Then scroll directly to the Content interface Scrolltocontentfromupmenu ();} else if (Updistancey < touchslop && isdownmenuvisible) {//The current side menu is displayed, if the user clicks on the Content section, Then scroll directly to the Content interface Scrolltocontentfromdownmenu ();} Recyclevelocitytracker (); break;} return true;} /** * Create Velocitytracker objects and add touch events to the Velocitytracker. * * @param event * */private void Createvelocitytracker (Motionevent event) {if (Mvelocitytracker = = null) {MV Elocitytracker = Velocitytracker.obtain ();} Mvelocitytracker.addmovement (event);} /** * According to the distance of the finger movement, judge the current user's sliding intent, and then assign the slidestate to the corresponding sliding state value. * * @param MOVEDISTANCEX * Horizontal Movement Distance * @param movedistancey * longitudinal movement distance */private void Checkslidestate ( int Movedistancex, int movedistancey) {if (isupmenuvisible) {if (!issliding && Math.Abs (Movedistancey) >= touchslop && Movedistancey < 0) {issliding = True;slidestate = HIDE_UP_ MENU;}} else if (isdownmenuvisible) {if (!issliding && math.abs (movedistancey) >= touchslop && Movedistancey & Gt 0) {issliding = True;slidestate = Hide_down_menu;}} Else{if (!issliding && math.abs (movedistancey) >= touchslop && movedistancey > 0&& Math.Abs (Movedistancex) < Touchslop) {issliding = True;slidestate = Show_up_menu;contentlayoutparams.addrule ( Relativelayout.align_parent_top, 0); Contentlayoutparams.addrule (Relativelayout.align_parent_bottom); Contentlayout.setlayoutparams (contentlayoutparams);//If the user wants to swipe the upper-side menu, the upper-side menu is displayed, and the lower-side menu hides the upmenulayout.setvisibility ( view.visible);d ownmenulayout.setvisibility (View.gone);} else if (!issliding && math.abs (movedistancey) >= touchslop && Movedistancey < 0&& math.abs (Movedistancex) < Touchslop) {issliding = True;slidestate = Show_down_menu;contentlayouTparams.addrule (relativelayout.align_parent_bottom, 0); Contentlayoutparams.addrule (RelativeLayout.ALIGN_PARENT_ TOP); Contentlayout.setlayoutparams (contentlayoutparams);//If the user wants to slide the lower side menu, display the lower side menu, The upper side menu hides upmenulayout.setvisibility (view.gone);d ownmenulayout.setvisibility (view.visible);}} /** * Check the boundary value of the upper side menu during the swipe process to prevent the binding layout from sliding out of the screen. */private void Checkupmenuborder () {if (Contentlayoutparams.bottommargin > 0) {contentlayoutparams.bottommargin = 0;} else if (Contentlayoutparams.bottommargin <-upmenulayoutparams.height) {Contentlayoutparams.bottommargin =- Upmenulayoutparams.height;}} /** * Check the boundary value of the lower side menu during the swipe process to prevent the binding layout from sliding out of the screen. */private void Checkdownmenuborder () {if (Contentlayoutparams.topmargin > 0) {contentlayoutparams.topmargin = 0;} else if (Contentlayoutparams.topmargin <-downmenulayoutparams.height) {Contentlayoutparams.topmargin =- Downmenulayoutparams.height;}} /** * Determine if you should scroll to show the top menu. If your finger moves more than 1/2 of the width of the upper side menu, or if your finger moves faster than snap_velocity, * you should scroll to show the top menu. * * @return Returns TRUE if the upper side menu should be displayed, otherwise false. */private Boolean Shouldscrolltoupmenu () {return yup-ydown > UPMENULAYOUTPARAMS.HEIGHT/2 | | getscrollvelocity () &G T snap_velocity;} /** * Determine if you should scroll to show the lower side menu. If your finger moves more than 1/2 of the width of the lower side menu, or if your finger moves faster than snap_velocity, * you should scroll to show the lower side menu. * * @return Returns True if the lower side menu should be displayed, otherwise false.  */private Boolean Shouldscrolltodownmenu () {return ydown-yup > DOWNMENULAYOUTPARAMS.HEIGHT/2 | | getscrollvelocity () > snap_velocity;} /** * Determine if you should scroll from the top side menu to the content layout, if your finger moves more than 1/2 of the width of the upper menu, or if your finger moves faster than snap_velocity, * you should scroll from the top side menu to the content layout. * * @return Returns True if the content layout should be scrolled from the top-side menu, otherwise false is returned. */private Boolean Shouldscrolltocontentfromupmenu () {return ydown-yup > UPMENULAYOUTPARAMS.HEIGHT/2 | | getScrollVel Ocity () > snap_velocity;} /** * Determine if you should scroll from the lower side menu to the content layout, if your finger moves more than 1/2 of the width of the lower side menu, or if your finger moves faster than snap_velocity, * you should scroll from the lower side menu to the content layout. * * @return Returns True if the content layout should be scrolled from the lower side menu, otherwise false is returned. */private Boolean Shouldscrolltocontentfromdownmenu () {return yup-ydown > DOWNMENULAYOUTPARAMS.HEIGHT/2 | | getScrol Lvelocity () > snap_velocity;} /* * Gets the sliding speed of the finger on the binding layout. * * @return sliding speed, in units of how many pixel values are moved per second. */private int getscrollvelocity () {mvelocitytracker.computecurrentvelocity (+); int velocity = (int) Mvelocitytracker.getxvelocity (); return math.abs (velocity);} Class Upmenuscrolltask extends Asynctask<integer, Integer, integer> {@Overrideprotected integer doinbackground ( Integer ... speed) {int bottommargin = contentlayoutparams.bottommargin;//Scrolls the interface according to the incoming velocity, and jumps out of the loop when scrolling reaches the boundary value. while (true) {bottommargin = BottomMargin + speed[0];if (BottomMargin <-upmenulayoutparams.height) {bottommargin =-up Menulayoutparams.height;break;} if (BottomMargin > 0) {bottommargin = 0;break;} Publishprogress (bottommargin);//To have a scrolling effect, each cycle causes the thread to sleep for a period of time so that the naked eye can see the scrolling animation. Sleep (15);} if (Speed[0] > 0) {isupmenuvisible = false;} else {isupmenuvisible = true;} issliding = False;return bottommargin;} @Overrideprotected void Onprogressupdate (Integer ... bottommargin) {contentlayoutparams.bottommargin = Bottommargin[0 ];contentlayout.setlayoutparams (contentlayouTparams); Unfocusbindview ();} @Overrideprotected void OnPostExecute (Integer bottommargin) {contentlayoutparams.bottommargin = BottomMargin; Contentlayout.setlayoutparams (Contentlayoutparams);}} Class Downmenuscrolltask extends Asynctask<integer, Integer, integer> {@Overrideprotected integer doinbackground (Integer ... speed) {int topMargin = contentlayoutparams.topmargin;//Scrolls the interface according to the incoming speed, and jumps out of the loop when scrolling reaches the boundary value. while (true) {TopMargin = TopMargin + speed[0];if (TopMargin <-downmenulayoutparams.height) {TopMargin =-downmenulayo Utparams.height;break;} if (TopMargin > 0) {topMargin = 0;break;} Publishprogress (TopMargin);//To have a scrolling effect, each cycle causes the thread to sleep for a period of time so that the naked eye can see the scrolling animation. Sleep (15);} if (Speed[0] > 0) {isdownmenuvisible = false;} else {isdownmenuvisible = true;} issliding = False;return TopMargin;} @Overrideprotected void Onprogressupdate (Integer ... topMargin) {contentlayoutparams.topmargin = topmargin[0]; Contentlayout.setlayoutparams (Contentlayoutparams); Unfocusbindview ();} @Overrideprotected void OnposTexecute (Integer topMargin) {contentlayoutparams.topmargin = Topmargin;contentlayout.setlayoutparams ( contentlayoutparams);}} /** * Causes the current thread to sleep for a specified number of milliseconds. * * @param millis * Specifies how long the current thread sleeps, in milliseconds */private void sleep (long Millis) {try {thread.sleep (Millis);} catch (in Terruptedexception e) {e.printstacktrace ();}} /** * Use the focusable control to lose focus when sliding. */private void Unfocusbindview () {if (Mbindview! = null) {mbindview.setpressed (false); mbindview.setfocusable (false); Mbindview.setfocusableintouchmode (FALSE);}} /** * Scrolls the interface to the upper-side menu interface with a scrolling speed of-30. */public void Scrolltoupmenu () {new Upmenuscrolltask (). Execute (-30);} /** * Scrolls the interface to the lower menu interface with the scrolling speed set to-30. */public void Scrolltodownmenu () {new Downmenuscrolltask (). Execute (-30);} /** * Scrolls the interface from the top-side menu to the content interface, with the scrolling speed set to 30. */public void Scrolltocontentfromupmenu () {new Upmenuscrolltask (). Execute (30);} /** * Scrolls the interface from the lower side menu to the content interface with a scrolling speed of 30. */public void Scrolltocontentfromdownmenu () {new Downmenuscrolltask (). Execute (30);} /** * The upper side menu is completely displayed, this value is not valid during sliding. * * @return The upper side menu is fully displayed returns True, otherwise false is returned. */public Boolean isuplayoutvisible () {return isupmenuvisible;} /** * The lower side menu is completely displayed, this value is not valid during sliding. * * @return The lower side menu is fully displayed returns True, otherwise false is returned. */public Boolean isdownlayoutvisible () {return isdownmenuvisible;} /** * Reset the parameters of the upper-side menu, the lower-side menu, and the content layout in OnLayout. */@Overrideprotected void OnLayout (Boolean changed, int l, int t, int r, int b) {super.onlayout (changed, L, T, R, b); if (c hanged) {//Get upper side Menu Layout Object upmenulayout = Getchildat (0); upmenulayoutparams = (marginlayoutparams) Upmenulayout.getlayoutparams ();//Gets the lower-side Menu Layout Object downmenulayout = Getchildat (1);d Ownmenulayoutparams = ( Marginlayoutparams) Downmenulayout.getlayoutparams ();//Get Content Layout Object contentlayout = Getchildat (2); contentlayoutparams = (relativelayout.layoutparams) Contentlayout.getlayoutparams (); contentlayoutparams.height = ScreenHeight; Contentlayout.setlayoutparams (Contentlayoutparams);}} /** * Reclaims Velocitytracker objects. */private void Recyclevelocitytracker () {mvelocitytracker.recycle (); mvelocitytracker = null;}}

Here is the usage example:

Import Android.os.bundle;import Android.widget.arrayadapter;import Android.widget.linearlayout;import Android.widget.listview;import android.app.activity;/** * Sliding Menu Demo Main Activity * * @author Guolin */public class Mainactivi Ty2 extends Activity {/** * bidirectional sliding menu Layout */private upanddownslidinglayout updownsldinglayout;/** * ListView */privat displayed on content layout    e ListView contentlist; Private LinearLayout ll;/** * ListView Adapter */private arrayadapter<string> contentlistadapter;/** * The data source used to populate the contentlistadapter. */private string[] Contentitems = {"Content Item 1", "Content Item 2", "Content Item 3", "Content Item 4", "Content Item 5 "," Content Item 6 "," Content Item 7 "," Content Item 8 "," Content Item 9 "," Content item "," Content Item One "," content It Em "," Content item "," Content item "," Content item "," Content Item "}; @Overrideprotected void OnCreate (Bundl E savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main2); ll = ( LinearLayout) Findviewbyid(r.id.content); updownsldinglayout = (upanddownslidinglayout) Findviewbyid (r.id.updown_sliding_layout); contentList = (ListView) Findviewbyid (r.id.contentlist); contentlistadapter = new Arrayadapter<string> (this, Android. R.layout.simple_list_item_1,contentitems); Contentlist.setadapter (Contentlistadapter); Updownsldinglayout.setscrollevent (ll);}}

Layout file:

<com.example.upanddownslidinglayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= " Http://schemas.android.com/tools "android:id=" @+id/updown_sliding_layout "android:layout_width=" Fill_parent "Android oid:layout_height= "Fill_parent" > <relativelayout android:id= "@+id/up_menu" android:layout_width= "f Ill_parent "android:layout_height=" 300DP "android:layout_alignparenttop=" true "android:background=" #0            0CCFF "android:visibility=" invisible "> <textview android:layout_width=" wrap_content " android:layout_height= "Wrap_content" android:layout_centerinparent= "true" android:text= "this I s up menu "android:textcolor=" #000000 "android:textsize=" 28sp "/> </RelativeLayout> & Lt Relativelayout android:id= "@+id/down_menu" android:layout_width= "Fill_parent" android:layout_height= " 300DP "Android:layout_Alignparentbottom= "true" android:background= "#00ffcc" android:visibility= "invisible" > <textvie W android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" android:layout _centerinparent= "true" android:text= "This was down menu" android:textcolor= "#000000" Andro Id:textsize= "28sp"/> </RelativeLayout> <linearlayout android:id= "@+id/content" Android:la Yout_width= "Fill_parent" android:layout_height= "fill_parent" android:gravity= "center" Android:backgro und= "#e9e9e9" > <listview android:id= "@+id/contentlist" android:layout_width= "Fill_pare NT "android:layout_height=" 500DP "android:scrollbars=" None "android:cachecolorhint=" #0000 0000 "> </ListView> </LinearLayout></com.example.UpAndDownSlidinglayout>




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.