Android and android Official Website
Implementation Principle
There must be two parts in the layout of an Activity. One is the layout of menus and the other is the layout of content. The two la s are arranged horizontally. The menu is left and the content is right.At initialization, the menu layout is shifted to the left to be completely hidden.In this way, the content layout is fully displayed in the Activity.Then, the left offset distance of the menu layout is changed by listening to the finger sliding event to control the display and hiding of the menu layout.
Layout
<LinearLayout 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" android:orientation="horizontal" tools:context=".MyActivity"> <LinearLayout android:id="@+id/menu" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ff00ff00" android:orientation="vertical"></LinearLayout> <LinearLayout android:id="@+id/content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffff0000" android:orientation="vertical"></LinearLayout></LinearLayout>
The outermost layout of the layout file is a LinearLayout, which is arranged horizontally. Under this LinearLayout, two sublinearlayout elements are nested, namely, the menu layout and the content layout. In order to make the layout as simple as possible, no controls are added to the menu layout and content layout.
Code
Public class MyActivity extends Activity implements View. onTouchListener {/*** the finger slides 200 pixels per unit of time */private static final int SPEED = 200;/*** screen width */private int mScreenWidth; /* ** menu layout */private LinearLayout mMenuLayout;/* ** content layout */private LinearLayout mContentLayout;/*** menu Paramters */private LinearLayout. layoutParams mMenuParams;/*** width of the content when the menu is fully displayed */Private int mMenuPadding = 80;/*** menu slides to the left edge at most. The value is determined by the width of the menu layout. After marginLeft reaches this value, you cannot reduce */private int mLeftEdge;/*** object of test speed */private VelocityTracker mVelocityTracker;/*** X coordinate pressed by finger */private float mXDown; /* X coordinate */private float mXMove when the finger moves;/* X coordinate raised by the finger */private float mXUp; /*** whether the menu is displayed */private boolean mIsMenuVisible = false; @ Override protected void onCreate (Bundle savedI NstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_my); initViewsAndValues (); mContentLayout. setOnTouchListener (this);}/*** initialize menu and content and set their location */private void initViewsAndValues () {// get windowManager WindowManager window = (WindowManager) getSystemService (Context. WINDOW_SERVICE); // obtain the screen width mScreenWidth = window. getdefadisplay display (). getWidth (); // locate the control mMenuL Ayout = (LinearLayout) findViewById (R. id. menu); mContentLayout = (LinearLayout) findViewById (R. id. content); // obtain the paramter mMenuParams = (LinearLayout. layoutParams) mMenuLayout. getLayoutParams (); // set the menu width to the screen width minus mMenuPading mMenuParams. width = mScreenWidth-mMenuPadding; // copy the value of the left edge to a negative value of the menu width, so that the menu can be hidden mLeftEdge =-mMenuParams. width; // set margin to mLeftEdge mMenuParams. leftMargin = mLeftEd Ge; // display the content before mContentLayout. getLayoutParams (). width = mScreenWidth;} @ Override public boolean onTouch (View view, MotionEvent event) {createVelocityTracker (event); switch (event. getAction () {case MotionEvent. ACTION_DOWN: // record X coordinate mXDown = event. getRawX (); break; case MotionEvent. ACTION_MOVE: mXMove = event. getRawX (); int distanceX = (int) (mXMove-mXDown); if (mIsMenuVisible) {mMenuPar Ams. leftMargin = distanceX;} else {mMenuParams. leftMargin = mLeftEdge + distanceX;} if (mMenuParams. leftMargin <mLeftEdge) {// because leftEdge is a negative number, the menu has been hidden, and mMenuParams cannot be hidden from the left. leftMargin = mLeftEdge;} else if (mMenuParams. leftMargin> 0) {// The menu is completely displayed and cannot be moved to the right. leftMargin = 0;} mMenuLayout. setLayoutParams (mMenuParams); break; case MotionEvent. ACTION_UP: mXUp = event. getRawX (); if (WantToShowMenu () {if (shouldScrollToMenu () {scrollToMenu () ;}else {// The menu is hidden from scrollToContent ();}} else if (wantToShowContent () {if (shouldScrollToContent () {scrollToContent () ;}else {scrollToMenu () ;}} break ;} recycleVelocityTracker (); return true ;} /*** create a VelocityTracker object for sliding events on the content interface ** @ param event */private void createVelocityTracker (MotionEvent event) {if (Null = mVelocityTracker) {mVelocityTracker = VelocityTracker. obtain ();} mVelocityTracker. addMovement (event);}/*** determine whether the gesture is intended to display Content & menu in display status ** @ return */private boolean wantToShowContent () {return mXUp-mXDown <0 & mIsMenuVisible;}/*** is it necessary to display the menu & menu in the hidden state ** @ return */private boolean wantToShowMenu () {return mXUp-mXDown> 0 &&! MIsMenuVisible;}/*** whether menu ** @ return */private boolean shouldScrollToMenu () {return mXUp-mXDown> mScreenWidth/2 | getScrollVelocity ()> SPEED;}/*** whether to display all content ** @ return */private boolean shouldScrollToContent () {return mXDown-mXUp <mScreenWidth/2 | getScrollVelocity ()> SPEED;}/*** display menu */private void scrollToMenu () {new scrollasynctask(cmd.exe cute (30 ); }/*** Hide menu */private void scrollToContent () {new scrollasynctask(.exe cute (-30);}/*** to get the finger sliding speed, how many pixels are moved per second ** @ return */private int getScrollVelocity () {mVelocityTracker. computeCurrentVelocity (1000); int velocity = (int) mVelocityTracker. getXVelocity (); return Math. abs (velocity);}/*** reclaim the VelocityTracker object. */Private void recycleVelocityTracker () {mVelocityTracker. recycle (); mVelocityTracker = null;} class ScrollAsyncTask extends AsyncTask <Integer, Integer, Integer> {@ Override protected Integer doInBackground (Integer [] speed) {// obtain the current margin int leftMargin = mMenuParams. leftMargin; // constantly change the value of margin while (true) {leftMargin = leftMargin + speed [0]; if (leftMargin> 0) {leftMargin = 0; break ;} if (leftMargin <mLeftEdge) {leftMargin = mLeftEdge; break;} publishProgress (leftMargin); sleep ();} if (speed [0]> 0) {mIsMenuVisible = true ;} else {mIsMenuVisible = false;} return leftMargin;} @ Override protected void onPostExecute (Integer integer) {mMenuParams. leftMargin = integer; mMenuLayout. setLayoutParams (mMenuParams);} @ Override protected void onProgressUpdate (Integer... values) {mMenuParams. leftMargin = values [0]; mMenuLayout. setLayoutParams (mMenuParams);}/*** sleep Thread sleep */private void sleep () {try {Thread. sleep (20);} catch (InterruptedException e) {e. printStackTrace ();}}}
Call the initViewsAndValues method during initialization. Set the content layout width to the screen width, and the menu layout width to the screen width minus the menuPadding value, this ensures that some content la s are displayed during the menu layout. If you do not re-define the two layout widths during initialization, the layout will be declared as the same as in the layout file. Both layout are fill_parent, so that the sliding menu cannot be achieved. Then, set the left offset of the menu layout to the width of the negative menu layout, so that the menu layout will be completely hidden, and only the content layout will be displayed on the interface.
Then register the listening event for the content layout, so that the onTouch event will be triggered when the finger slides over the content layout. In the onTouch event, the left offset of the menu layout is changed based on the sliding distance of the finger to control the display and hiding of the menu layout. When the finger leaves the screen, it will determine whether to slide to the menu layout or content layout. The judgment is based on the sliding distance or speed of the finger. For details, see the comments in the code.
I am the dividing line of tiantiao
Demo: https://github.com/pinguo-yuyidong/SlidingMenuDemo
Reference: http://blog.csdn.net/guolin_blog/article/details/8714621