Android slide menu complete example (domestic version)

Source: Internet
Author: User

Android slide menu complete example (domestic version)
MainActivity is 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: * encapsulate the slide menu used in Patience5 as a custom control to facilitate reuse. ** the differences between the example and Patience5 are as follows: * 1 Patience5 adopts the LinearLayout layout, and the custom control inherits from RelativeLayout * 2. In Patience5, it constantly changes the leftMargin of menuView, where it constantly changes contentView * rightMargin. note This when reading the code. ** references: * 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
 
  
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); // The sliding event is bound to mSlidingMenuRelativeLayout on contentListView. setBindView (mContentListView); initListViewData (); mArrayAdapter = new ArrayAdapter
  
   
(MContext, android. R. layout. parameters, listViewItems); mContentListView. setAdapter (mArrayAdapter); mContentListView. setOnItemClickListener (new OnItemClickListener () {@ Overridepublic void onItemClick (AdapterView)
   Arg0, View arg1, int position, long arg3) {String item = listViewItems [position]; Toast. makeText (mContext, item, Toast. LENGTH_SHORT ). show () ;}}) ;}private void initListViewData () {String temp = null; for (int I = 0; I <20; I ++) {temp = "This is" + I; listViewItems [I] = temp ;}}}
  
 


SlidingMenuRelativeLayout is 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: * 1 this custom control inherits from RelativeLay Out * 2 has two parts in the layout file: menuView and contentView. because the layout is RelativeLayout *, the two are overlapping. * 3. By constantly changing the rightMargin value of contentView to display and hide the menuView * 4. Note that the contentView alignparentright setting in the xml layout file sets the menuView alignparentright setting to android: layout_alignParentLeft. * pay attention to the Code: * // set the minimum and maximum rightMargin values of contentView * contentParamsMinRightMargin =-mMenuLayoutParams. width; * contentParamsMaxRightMargin = 0; * This is clever. because contentView is right aligned with the parent Control. So in the original state, * the value of his rightMargin is 0. when your fingers slide to the right of the screen by pressing contentView, you can reduce * its rightMargin. As a result, the contentView moves to the right of the screen, which is originally covered by its menuView. * therefore, the maximum rightMargin value of contentView is 0. This is what we can see after entering the App: * The contentView is displayed, and the menuView is hidden. its rightMargin = 0; alignment to the right of the parent control. * When contentView moves to the right of the screen, its rightMargin gradually decreases until the absolute value of rightMargin * is the width of the menuView. * ** code details: * 1 mMenuLayoutParams and mContentLayoutParams are of the * MarginLayoutParams type, because menuView And the conentView parent control * is a custom SlidingMenuRelativeLayout, instead of the commonly used system XXXLayout * 2 slide the finger on the ListView and then lift it up, sometimes the ListView item is pressed and does not pop up. the cause is unknown for the moment, but the unFocusBindView () method can be used to cause * ListView to lose focus. this method is called twice in the example. you can comment it out and observe the effect. * There are still small bugs in the code. you need to continue optimization 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; private float yMove; private float yUp; private Button mButton; private Context mContext; // whether the current sliding private boolean isSliding; // The maximum private int scaledTouchSlop that the user's finger can move before being determined to be scroll; // whether the menu is visible flag, this value is invalid during sliding. // This value is changed only when the menu is fully displayed or hidden after sliding. private boolean isMenuVisible = false; private int contentParamsMaxRightMargin = 0; private int conte NtParamsMinRightMargin = 0; // speed tracking private VelocityTracker mVelocityTracker; // The public static final int VELOCITY_THRESHOLD = 200; // TAGprivate final static String TAG = "SlidingMenuRelativeLayout "; // menu LayoutParamsprivate MarginLayoutParams mMenuLayoutParams; // content LayoutParamsprivate MarginLayoutParams mContentLayoutParams; public topology (Context context) {super (contex T);} public SlidingMenuRelativeLayout (Context context, AttributeSet attrs) {super (context, attrs); init (context);} public partition (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 (changed) {// initialize contentViewcontentView = getChildAt (1); mContentLayoutParams = (MarginLayoutParams) contentView. getLayoutParams (); // set the width of contentView to the width of the screen. width = screenWidth; contentView. setLayoutParams (mContentLayoutParams); // initialize menuViewmenuView = getChildAt (0); mMenuLayoutParams = (MarginLayoutParams) menuView. getLayoutParams (); // sets the minimum and maximum rightMargin values of contentView. contentParamsMinRightMargin =-mMenuLayoutParams. width; contentPa RamsMaxRightMargin = 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; // obtain the screen width WindowManager windowManager = (WindowManager) mContext. getSystemService (Context. WINDOW_SERVICE); s CreenWidth = windowManager. getdefadisplay display (). getWidth (); // obtain ScaledTouchSlopscaledTouchSlop = ViewConfiguration. get (context ). getScaledTouchSlop ();}/*** the View that registers for Touch event processing processes the ListView Touch to display and hide the menuView. * In actual development, you can set other controls as needed */public void setBindView (View bindView) {mBindView = bindView; mBindView. setOnTouchListener (new TouchListenerImpl ();} // make BindView 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) {// 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); // slide the finger to the right of the screen, distanceX is a positive number if (! IsMenuVisible & distanceX> = scaledTouchSlop & (isSliding | Math. abs (distanceY) <= scaledTouchSlop) {isSliding = true; mContentLayoutParams. rightMargin =-distanceX; // if (mContentLayoutParams. rightMargin <contentParamsMinRightMargin) {mContentLayoutParams. rightMargin = contentParamsMinRightMargin;} // set the LayoutParamscontentView of contentView. setLayoutParams (mContentLayoutParams);} // slide your finger to the left of the screen, DistanceX is negative. if (isMenuVisible &-distanceX> = scaledTouchSlop) {isSliding = true; mContentLayoutParams. rightMargin = contentParamsMinRightMargin-distanceX; // if (mContentLayoutParams. rightMargin> contentParamsMaxRightMargin) {mContentLayoutParams. rightMargin = contentParamsMaxRightMargin;} // set the LayoutParamscontentView of contentView. setLayoutParams (mContentLayoutParams);} break; case MotionEve Nt. ACTION_UP: xUp = event. getRawX (); int upDistanceX = (int) (xUp-xDown); if (isSliding) {// determine the gesture intention to display menuif (wantToShowMenu ()) {// determine whether to display menuif (shouldScrollToMenu () {scrollToMenu () ;}else {scrollToContent () ;}// determine whether the gesture intent is to display contentif (wantToShowContent ()) {// determine whether to display contentif (shouldScrollToContent () {scrollToContent () ;}else {scrollToMenu () ;}} else {// when the menu interface is fully displayed, click only the contentView you can see to display it completely if (upDi StanceX <scaledTouchSlop & isMenuVisible) {scrollToContent () ;}// stop speed tracking stopVelocityTracker (); break; default: break ;}/ *** after processing is completed, MOVE, UP and then perform the if... else judgment. * 1 if it is not in the slide status, false is returned. otherwise, ListView cannot slide and its Item cannot be clicked. * 2 if sliding, The ListView will lose its focus. */if (! IsSliding) {return false;} else {unFocusBindView ();} return true;}/*** determine whether the current gesture wants to display the Menu * judgment condition: * 1 lift coordinates greater than pressing coordinates * 2 menu itself invisible */private boolean wantToShowMenu () {return (xUp-xDown> 0 )&&(! IsMenuVisible);}/*** determines whether the menu should be completely displayed * judgment condition: sliding distance greater than 1/2 * of the menu or sliding speed greater than the speed threshold VELOCITY_THRESHOLD */private boolean shouldScrollToMenu () {return (xUp-xDown> mMenuLayoutParams. width/2) | (getScrollVelocity ()> VELOCITY_THRESHOLD);}/*** scroll the screen to the menu. displays the complete menu. */public void scrollToMenu () {new scrollasynctask(.exe cute (-30);}/*** determine whether the current gesture wants to display the menu Content * judgment condition: * 1 lift coordinates less than pressing coordinates * 2 menu itself visible */priva Te boolean wantToShowContent () {return (xUp-xDown <0) & (isMenuVisible);}/*** determine whether the content should be completely displayed * judgment condition: sliding distance greater than 1/2 * of the menu or sliding speed greater than the speed threshold VELOCITY_THRESHOLD */private boolean shouldScrollToContent () {return (xDown-xUp> mMenuLayoutParams. width/2) | (getScrollVelocity ()> VELOCITY_THRESHOLD);}/*** scroll the screen to the content. displays the full content */public void scrollToContent () {new scrollasynctask(cmd.exe cute (30);} public boolean isMenuVisible () {return isMenuVisible;}/*** Start Speed Tracing */private void startVelocityTracker (MotionEvent event) {if (mVelocityTracker = null) {mVelocityTracker = VelocityTracker. obtain ();} mVelocityTracker. addMovement (event);}/*** get the finger sliding speed X on the content */private int getScrollVelocity () {// set the VelocityTracker unit. 1000 indicates the pixel mVelocityTracker that moves within 1 second. computeCurrentVelocity (1000); // get X in 1 second The sliding pixel value int xVelocity = (int) mVelocityTracker. getXVelocity (); return Math. abs (xVelocity);}/*** end speed tracking */private void stopVelocityTracker () {if (mVelocityTracker! = Null) {mVelocityTracker. recycle (); mVelocityTracker = null;}/*** use an asynchronous task to constantly modify the rightMargin in the LayoutParams of contentView to achieve the effect of moving the contentView view */private class ScrollAsyncTask extends AsyncTask
 
  
{@ Overrideprotected Integer doInBackground (Integer... speed) {int contentLayoutParamsRightMargin = mContentLayoutParams. rightMargin; while (true) {// response of each change = contentLayoutParamsRightMargin + speed [0]; // if this parameter is out of bounds, the request is processed out of bounds and out of the loop if) {response = contentParamsMaxRightMargin; break;} // if the request is out of the permitted range, the request is out of the permitted range. if (Response <contentParamsMinRightMargin) {contentLayoutParamsRightMargin; break ;} // notification progress update publishProgress (contentLayoutParamsRightMargin); // The Thread sleeps for 15 milliseconds to facilitate the scrolling effect try {Thread. sleep (15);} catch (Exception e) {}} // set the flag isMenuVisibleif (speed [0]> 0) {isMenuVisible = false ;} else {isMenuVisible = true;} 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 is as follows:

     
          
           
       
      
          
           
       
  
 


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.