标签:des   android   style   blog   http   io   color   os   ar   
 本文由 孙国威 原创。如需转载,请注明出处! 
 
 
 
 
 为了后续对这个项目进行优化,比如透明度动画、背景图的位移动画,以及性能上的优化。 
 
 我把这个项目上传到github上面,请大家随时关注。 
 
 github地址 https://github.com/sunguowei 
 
 
 
 
 最近项目要做一个QQ5.0的侧滑菜单效果,和传统的侧滑菜单存在着一些差异。想必大家都已经见识过了。 
 
 为了不重复发明轮子,先去github上面搜索了一番。 
 
 发现了几个类似的,但是还是有一些不同。 
 
 下面是搜索到的类似的开源项目。 
 
 RESideMenu(ios项目) 
 
 https://github.com/romaonthego/RESideMenu 
 
  
 
 
 AndroidResideMenu 
 
 https://github.com/SpecialCyCi/AndroidResideMenu 
 
  
 
 
 ResideLayout 
 
 https://github.com/kyze8439690/ResideLayout 
 
  
 
 
 
 
 
 研究了一下这些开源项目的源代码。感觉并不是特别适用于我们自己的项目。所以,我自己又研究了一下。最后的效果如下。当然了,还有很多可以优化的地方,后续再慢慢优化。 
 
  
 
 
 备注:如果图片动画显示不出来,可以点击这个网址查看。 
 
 http://img.blog.csdn.net/20140902225149282?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFub2Vs/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast 
 
 
 
 
 我是基于SlidingMenu库进行的二次修改,增加了一些转场动画。 
 
 大家对这个库应该比较熟悉,下面是SlidingMenu的github地址。非常感谢Jeremy Feinstein提供的这个库,让广大Android Developers省去了非常多的麻烦。 
 
 https://github.com/jfeinstein10/SlidingMenu 
 
 备注:SlidingMenu使用了SherlockActionBar这个库,配置起来会比较麻烦,在文章的最后我会把demo上传,供大家下载,减去了大家自己配置项目的麻烦。 
 
 我主要修改了2个类,SlidingMenu.java和CustonViewAbove.java,只是增加了一些功能,并没有修改原本的功能。 
 
 做了修改的地方,我做了中文注释,其实实现很简单,几行代码而已。推荐大家下载Demo,然后自己调试一下。Demo的下载地址在文章的末尾。 
 
 废话不多说,直接上代码,略微有点长。 
 
 
  
  
  -  public class SlidingMenu extends RelativeLayout {   
-     
-      private static final String TAG = SlidingMenu.class.getSimpleName();   
-     
-      public static final int SLIDING_WINDOW = 0;   
-      public static final int SLIDING_CONTENT = 1;   
-      private boolean mActionbarOverlay = false;   
-     
-      /**  
-       * Constant value for use with setTouchModeAbove(). Allows the SlidingMenu  
-       * to be opened with a swipe gesture on the screen‘s margin  
-       */   
-      public static final int TOUCHMODE_MARGIN = 0;   
-     
-      /**  
-       * Constant value for use with setTouchModeAbove(). Allows the SlidingMenu  
-       * to be opened with a swipe gesture anywhere on the screen  
-       */   
-      public static final int TOUCHMODE_FULLSCREEN = 1;   
-     
-      /**  
-       * Constant value for use with setTouchModeAbove(). Denies the SlidingMenu  
-       * to be opened with a swipe gesture  
-       */   
-      public static final int TOUCHMODE_NONE = 2;   
-     
-      /**  
-       * Constant value for use with setMode(). Puts the menu to the left of the  
-       * content.  
-       */   
-      public static final int LEFT = 0;   
-     
-      /**  
-       * Constant value for use with setMode(). Puts the menu to the right of the  
-       * content.  
-       */   
-      public static final int RIGHT = 1;   
-     
-      /**  
-       * Constant value for use with setMode(). Puts menus to the left and right  
-       * of the content.  
-       */   
-      public static final int LEFT_RIGHT = 2;   
-     
-      private CustomViewAbove mViewAbove;   
-     
-      private CustomViewBehind mViewBehind;   
-     
-          /** 整体的背景,用一个ImageView代替 */   
-      private ImageView mViewBackground;   
-     
-      private OnOpenListener mOpenListener;   
-     
-      private OnOpenListener mSecondaryOpenListner;   
-     
-      private OnCloseListener mCloseListener;   
-     
-      /**  
-       * The listener interface for receiving onOpen events. The class that is  
-       * interested in processing a onOpen event implements this interface, and  
-       * the object created with that class is registered with a component using  
-       * the component‘s <code>addOnOpenListener<code> method. When  
-       * the onOpen event occurs, that object‘s appropriate  
-       * method is invoked  
-       */   
-      public interface OnOpenListener {   
-     
-          /**  
-           * On open.  
-           */   
-          public void onOpen();   
-      }   
-     
-      /**  
-       * The listener interface for receiving onOpened events. The class that is  
-       * interested in processing a onOpened event implements this interface, and  
-       * the object created with that class is registered with a component using  
-       * the component‘s <code>addOnOpenedListener<code> method. When  
-       * the onOpened event occurs, that object‘s appropriate  
-       * method is invoked.  
-       *   
-       * @see OnOpenedEvent  
-       */   
-      public interface OnOpenedListener {   
-     
-          /**  
-           * On opened.  
-           */   
-          public void onOpened();   
-      }   
-     
-      /**  
-       * The listener interface for receiving onClose events. The class that is  
-       * interested in processing a onClose event implements this interface, and  
-       * the object created with that class is registered with a component using  
-       * the component‘s <code>addOnCloseListener<code> method. When  
-       * the onClose event occurs, that object‘s appropriate  
-       * method is invoked.  
-       *   
-       * @see OnCloseEvent  
-       */   
-      public interface OnCloseListener {   
-     
-          /**  
-           * On close.  
-           */   
-          public void onClose();   
-      }   
-     
-      /**  
-       * The listener interface for receiving onClosed events. The class that is  
-       * interested in processing a onClosed event implements this interface, and  
-       * the object created with that class is registered with a component using  
-       * the component‘s <code>addOnClosedListener<code> method. When  
-       * the onClosed event occurs, that object‘s appropriate  
-       * method is invoked.  
-       *   
-       * @see OnClosedEvent  
-       */   
-      public interface OnClosedListener {   
-     
-          /**  
-           * On closed.  
-           */   
-          public void onClosed();   
-      }   
-     
-      /**  
-       * The Interface CanvasTransformer.  
-       */   
-      public interface CanvasTransformer {   
-     
-          /**  
-           * Transform canvas.  
-           *   
-           * @param canvas  
-           *            the canvas  
-           * @param percentOpen  
-           *            the percent open  
-           */   
-          public void transformCanvas(Canvas canvas, float percentOpen);   
-      }   
-     
-      /**  
-       * Instantiates a new SlidingMenu.  
-       *   
-       * @param context  
-       *            the associated Context  
-       */   
-      public SlidingMenu(Context context) {   
-          this(context, null);   
-      }   
-     
-      /**  
-       * Instantiates a new SlidingMenu and attach to Activity.  
-       *   
-       * @param activity  
-       *            the activity to attach slidingmenu  
-       * @param slideStyle  
-       *            the slidingmenu style  
-       */   
-      public SlidingMenu(Activity activity, int slideStyle) {   
-          this(activity, null);   
-          this.attachToActivity(activity, slideStyle);   
-      }   
-     
-      /**  
-       * Instantiates a new SlidingMenu.  
-       *   
-       * @param context  
-       *            the associated Context  
-       * @param attrs  
-       *            the attrs  
-       */   
-      public SlidingMenu(Context context, AttributeSet attrs) {   
-          this(context, attrs, 0);   
-      }   
-     
-      /**  
-       * Instantiates a new SlidingMenu.  
-       *   
-       * @param context  
-       *            the associated Context  
-       * @param attrs  
-       *            the attrs  
-       * @param defStyle  
-       *            the def style  
-       */   
-      public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {   
-          super(context, attrs, defStyle);   
-                  /** SlidingMenu是一个RelativeLayout,这里把背景图ImageView添加到RelativeLayout的最底层。*/   
-          LayoutParams backgroundParams = new LayoutParams(   
-                  LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);   
-          mViewBackground = new ImageView(context);   
-          mViewBackground.setScaleType(ImageView.ScaleType.CENTER_CROP);   
-          addView(mViewBackground, backgroundParams);   
-             
-                  LayoutParams behindParams = new LayoutParams(LayoutParams.MATCH_PARENT,   
-                  LayoutParams.MATCH_PARENT);   
-          mViewBehind = new CustomViewBehind(context);   
-          addView(mViewBehind, behindParams);   
-          LayoutParams aboveParams = new LayoutParams(LayoutParams.MATCH_PARENT,   
-                  LayoutParams.MATCH_PARENT);   
-          mViewAbove = new CustomViewAbove(context);   
-          addView(mViewAbove, aboveParams);   
-          // register the CustomViewBehind with the CustomViewAbove   
-          mViewAbove.setCustomViewBehind(mViewBehind);   
-          mViewBehind.setCustomViewAbove(mViewAbove);   
-          mViewAbove.setOnPageChangeListener(new OnPageChangeListener() {   
-              public static final int POSITION_OPEN = 0;   
-              public static final int POSITION_CLOSE = 1;   
-              public static final int POSITION_SECONDARY_OPEN = 2;   
-     
-              public void onPageScrolled(int position, float positionOffset,   
-                      int positionOffsetPixels) {   
-              }   
-     
-              public void onPageSelected(int position) {   
-                  if (position == POSITION_OPEN && mOpenListener != null) {   
-                      mOpenListener.onOpen();   
-                  } else if (position == POSITION_CLOSE && mCloseListener != null) {   
-                      mCloseListener.onClose();   
-                  } else if (position == POSITION_SECONDARY_OPEN   
-                          && mSecondaryOpenListner != null) {   
-                      mSecondaryOpenListner.onOpen();   
-                  }   
-              }   
-          });   
-     
-          // now style everything!   
-          TypedArray ta = context.obtainStyledAttributes(attrs,   
-                  R.styleable.SlidingMenu);   
-          // set the above and behind views if defined in xml   
-          int mode = ta.getInt(R.styleable.SlidingMenu_mode, LEFT);   
-          setMode(mode);   
-          int viewAbove = ta.getResourceId(R.styleable.SlidingMenu_viewAbove, -1);   
-          if (viewAbove != -1) {   
-              setContent(viewAbove);   
-          } else {   
-              setContent(new FrameLayout(context));   
-          }   
-          int viewBehind = ta.getResourceId(R.styleable.SlidingMenu_viewBehind,   
-                  -1);   
-          if (viewBehind != -1) {   
-              setMenu(viewBehind);   
-          } else {   
-              setMenu(new FrameLayout(context));   
-          }   
-          int touchModeAbove = ta.getInt(R.styleable.SlidingMenu_touchModeAbove,   
-                  TOUCHMODE_MARGIN);   
-          setTouchModeAbove(touchModeAbove);   
-          int touchModeBehind = ta.getInt(   
-                  R.styleable.SlidingMenu_touchModeBehind, TOUCHMODE_MARGIN);   
-          setTouchModeBehind(touchModeBehind);   
-     
-          int offsetBehind = (int) ta.getDimension(   
-                  R.styleable.SlidingMenu_behindOffset, -1);   
-          int widthBehind = (int) ta.getDimension(   
-                  R.styleable.SlidingMenu_behindWidth, -1);   
-          if (offsetBehind != -1 && widthBehind != -1)   
-              throw new IllegalStateException(   
-                      "Cannot set both behindOffset and behindWidth for a SlidingMenu");   
-          else if (offsetBehind != -1)   
-              setBehindOffset(offsetBehind);   
-          else if (widthBehind != -1)   
-              setBehindWidth(widthBehind);   
-          else   
-              setBehindOffset(0);   
-          float scrollOffsetBehind = ta.getFloat(   
-                  R.styleable.SlidingMenu_behindScrollScale, 0.33f);   
-          setBehindScrollScale(scrollOffsetBehind);   
-          int shadowRes = ta.getResourceId(   
-                  R.styleable.SlidingMenu_shadowDrawable, -1);   
-          if (shadowRes != -1) {   
-              setShadowDrawable(shadowRes);   
-          }   
-          int shadowWidth = (int) ta.getDimension(   
-                  R.styleable.SlidingMenu_shadowWidth, 0);   
-          setShadowWidth(shadowWidth);   
-          boolean fadeEnabled = ta.getBoolean(   
-                  R.styleable.SlidingMenu_fadeEnabled, true);   
-          setFadeEnabled(fadeEnabled);   
-          float fadeDeg = ta.getFloat(R.styleable.SlidingMenu_fadeDegree, 0.33f);   
-          setFadeDegree(fadeDeg);   
-          boolean selectorEnabled = ta.getBoolean(   
-                  R.styleable.SlidingMenu_selectorEnabled, false);   
-          setSelectorEnabled(selectorEnabled);   
-          int selectorRes = ta.getResourceId(   
-                  R.styleable.SlidingMenu_selectorDrawable, -1);   
-          if (selectorRes != -1)   
-              setSelectorDrawable(selectorRes);   
-          ta.recycle();   
-      }   
-     
-      /**  
-       * Attaches the SlidingMenu to an entire Activity  
-       *   
-       * @param activity  
-       *            the Activity  
-       * @param slideStyle  
-       *            either SLIDING_CONTENT or SLIDING_WINDOW  
-       */   
-      public void attachToActivity(Activity activity, int slideStyle) {   
-          attachToActivity(activity, slideStyle, false);   
-      }   
-     
-      /**  
-       * Attaches the SlidingMenu to an entire Activity  
-       *   
-       * @param activity  
-       *            the Activity  
-       * @param slideStyle  
-       *            either SLIDING_CONTENT or SLIDING_WINDOW  
-       * @param actionbarOverlay  
-       *            whether or not the ActionBar is overlaid  
-       */   
-      public void attachToActivity(Activity activity, int slideStyle,   
-              boolean actionbarOverlay) {   
-          if (slideStyle != SLIDING_WINDOW && slideStyle != SLIDING_CONTENT)   
-              throw new IllegalArgumentException(   
-                      "slideStyle must be either SLIDING_WINDOW or SLIDING_CONTENT");   
-     
-          if (getParent() != null)   
-              throw new IllegalStateException(   
-                      "This SlidingMenu appears to already be attached");   
-     
-          // get the window background   
-          TypedArray a = activity.getTheme().obtainStyledAttributes(   
-                  new int[] { android.R.attr.windowBackground });   
-          int background = a.getResourceId(0, 0);   
-          a.recycle();   
-     
-          switch (slideStyle) {   
-          case SLIDING_WINDOW:   
-              mActionbarOverlay = false;   
-              ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();   
-              ViewGroup decorChild = (ViewGroup) decor.getChildAt(0);   
-              // save ActionBar themes that have transparent assets   
-              decorChild.setBackgroundResource(background);   
-              decor.removeView(decorChild);   
-              decor.addView(this);   
-              setContent(decorChild);   
-              break;   
-          case SLIDING_CONTENT:   
-              mActionbarOverlay = actionbarOverlay;   
-              // take the above view out of   
-              ViewGroup contentParent = (ViewGroup) activity   
-                      .findViewById(android.R.id.content);   
-              View content = contentParent.getChildAt(0);   
-              contentParent.removeView(content);   
-              contentParent.addView(this);   
-              setContent(content);   
-              // save people from having transparent backgrounds   
-              if (content.getBackground() == null)   
-                  content.setBackgroundResource(background);   
-              break;   
-          }   
-      }   
-     
-      /**  
-       * Set the above view content from a layout resource. The resource will be  
-       * inflated, adding all top-level views to the above view.  
-       *   
-       * @param res  
-       *            the new content  
-       */   
-      public void setContent(int res) {   
-          setContent(LayoutInflater.from(getContext()).inflate(res, null));   
-      }   
-     
-      /**  
-       * Set the above view content to the given View.  
-       *   
-       * @param view  
-       *            The desired content to display.  
-       */   
-      public void setContent(View view) {   
-          mViewAbove.setContent(view);   
-          showContent();   
-      }   
-     
-      /**  
-       * 设置背景图片  
-       *   
-       * @param resid  
-       */   
-      public void setBackgroundImage(int resid) {   
-          mViewBackground.setBackgroundResource(resid);   
-      }   
-     
-      /**  
-       * Retrieves the current content.  
-       *   
-       * @return the current content  
-       */   
-      public View getContent() {   
-          return mViewAbove.getContent();   
-      }   
-     
-      /**  
-       * Set the behind view (menu) content from a layout resource. The resource  
-       * will be inflated, adding all top-level views to the behind view.  
-       *   
-       * @param res  
-       *            the new content  
-       */   
-      public void setMenu(int res) {   
-          setMenu(LayoutInflater.from(getContext()).inflate(res, null));   
-      }   
-     
-      /**  
-       * Set the behind view (menu) content to the given View.  
-       *   
-       * @param view  
-       *            The desired content to display.  
-       */   
-      public void setMenu(View v) {   
-          mViewBehind.setContent(v);   
-      }   
-     
-      /**  
-       * Retrieves the main menu.  
-       *   
-       * @return the main menu  
-       */   
-      public View getMenu() {   
-          return mViewBehind.getContent();   
-      }   
-     
-      /**  
-       * Set the secondary behind view (right menu) content from a layout  
-       * resource. The resource will be inflated, adding all top-level views to  
-       * the behind view.  
-       *   
-       * @param res  
-       *            the new content  
-       */   
-      public void setSecondaryMenu(int res) {   
-          setSecondaryMenu(LayoutInflater.from(getContext()).inflate(res, null));   
-      }   
-     
-      /**  
-       * Set the secondary behind view (right menu) content to the given View.  
-       *   
-       * @param view  
-       *            The desired content to display.  
-       */   
-      public void setSecondaryMenu(View v) {   
-          mViewBehind.setSecondaryContent(v);   
-          // mViewBehind.invalidate();   
-      }   
-     
-      /**  
-       * Retrieves the current secondary menu (right).  
-       *   
-       * @return the current menu  
-       */   
-      public View getSecondaryMenu() {   
-          return mViewBehind.getSecondaryContent();   
-      }   
-     
-      /**  
-       * Sets the sliding enabled.  
-       *   
-       * @param b  
-       *            true to enable sliding, false to disable it.  
-       */   
-      public void setSlidingEnabled(boolean b) {   
-          mViewAbove.setSlidingEnabled(b);   
-      }   
-     
-      /**  
-       * Checks if is sliding enabled.  
-       *   
-       * @return true, if is sliding enabled  
-       */   
-      public boolean isSlidingEnabled() {   
-          return mViewAbove.isSlidingEnabled();   
-      }   
-     
-      /**  
-       * Sets which side the SlidingMenu should appear on.  
-       *   
-       * @param mode  
-       *            must be either SlidingMenu.LEFT or SlidingMenu.RIGHT  
-       */   
-      public void setMode(int mode) {   
-          if (mode != LEFT && mode != RIGHT && mode != LEFT_RIGHT) {   
-              throw new IllegalStateException(   
-                      "SlidingMenu mode must be LEFT, RIGHT, or LEFT_RIGHT");   
-          }   
-          mViewBehind.setMode(mode);   
-      }   
-     
-      /**  
-       * Returns the current side that the SlidingMenu is on.  
-       *   
-       * @return the current mode, either SlidingMenu.LEFT or SlidingMenu.RIGHT  
-       */   
-      public int getMode() {   
-          return mViewBehind.getMode();   
-      }   
-     
-      /**  
-       * Sets whether or not the SlidingMenu is in static mode (i.e. nothing is  
-       * moving and everything is showing)  
-       *   
-       * @param b  
-       *            true to set static mode, false to disable static mode.  
-       */   
-      public void setStatic(boolean b) {   
-          if (b) {   
-              setSlidingEnabled(false);   
-              mViewAbove.setCustomViewBehind(null);   
-              mViewAbove.setCurrentItem(1);   
-              // mViewBehind.setCurrentItem(0);   
-          } else {   
-              mViewAbove.setCurrentItem(1);   
-              // mViewBehind.setCurrentItem(1);   
-              mViewAbove.setCustomViewBehind(mViewBehind);   
-              setSlidingEnabled(true);   
-          }   
-      }   
-     
-      /**  
-       * Opens the menu and shows the menu view.  
-       */   
-      public void showMenu() {   
-          showMenu(true);   
-      }   
-     
-      /**  
-       * Opens the menu and shows the menu view.  
-       *   
-       * @param animate  
-       *            true to animate the transition, false to ignore animation  
-       */   
-      public void showMenu(boolean animate) {   
-          mViewAbove.setCurrentItem(0, animate);   
-      }   
-     
-      /**  
-       * Opens the menu and shows the secondary menu view. Will default to the  
-       * regular menu if there is only one.  
-       */   
-      public void showSecondaryMenu() {   
-          showSecondaryMenu(true);   
-      }   
-     
-      /**  
-       * Opens the menu and shows the secondary (right) menu view. Will default to  
-       * the regular menu if there is only one.  
-       *   
-       * @param animate  
-       *            true to animate the transition, false to ignore animation  
-       */   
-      public void showSecondaryMenu(boolean animate) {   
-          mViewAbove.setCurrentItem(2, animate);   
-      }   
-     
-      /**  
-       * Closes the menu and shows the above view.  
-       */   
-      public void showContent() {   
-          showContent(true);   
-      }   
-     
-      /**  
-       * Closes the menu and shows the above view.  
-       *   
-       * @param animate  
-       *            true to animate the transition, false to ignore animation  
-       */   
-      public void showContent(boolean animate) {   
-          mViewAbove.setCurrentItem(1, animate);   
-      }   
-     
-      /**  
-       * Toggle the SlidingMenu. If it is open, it will be closed, and vice versa.  
-       */   
-      public void toggle() {   
-          toggle(true);   
-      }   
-     
-      /**  
-       * Toggle the SlidingMenu. If it is open, it will be closed, and vice versa.  
-       *   
-       * @param animate  
-       *            true to animate the transition, false to ignore animation  
-       */   
-      public void toggle(boolean animate) {   
-          if (isMenuShowing()) {   
-              showContent(animate);   
-          } else {   
-              showMenu(animate);   
-          }   
-      }   
-     
-      /**  
-       * Checks if is the behind view showing.  
-       *   
-       * @return Whether or not the behind view is showing  
-       */   
-      public boolean isMenuShowing() {   
-          return mViewAbove.getCurrentItem() == 0   
-                  || mViewAbove.getCurrentItem() == 2;   
-      }   
-     
-      /**  
-       * Checks if is the behind view showing.  
-       *   
-       * @return Whether or not the behind view is showing  
-       */   
-      public boolean isSecondaryMenuShowing() {   
-          return mViewAbove.getCurrentItem() == 2;   
-      }   
-     
-      /**  
-       * Gets the behind offset.  
-       *   
-       * @return The margin on the right of the screen that the behind view  
-       *         scrolls to  
-       */   
-      public int getBehindOffset() {   
-          return ((RelativeLayout.LayoutParams) mViewBehind.getLayoutParams()).rightMargin;   
-      }   
-     
-      /**  
-       * Sets the behind offset.  
-       *   
-       * @param i  
-       *            The margin, in pixels, on the right of the screen that the  
-       *            behind view scrolls to.  
-       */   
-      public void setBehindOffset(int i) {   
-          // RelativeLayout.LayoutParams params =   
-          // ((RelativeLayout.LayoutParams)mViewBehind.getLayoutParams());   
-          // int bottom = params.bottomMargin;   
-          // int top = params.topMargin;   
-          // int left = params.leftMargin;   
-          // params.setMargins(left, top, i, bottom);   
-          mViewBehind.setWidthOffset(i);   
-      }   
-     
-      /**  
-       * Sets the behind offset.  
-       *   
-       * @param resID  
-       *            The dimension resource id to be set as the behind offset. The  
-       *            menu, when open, will leave this width margin on the right of  
-       *            the screen.  
-       */   
-      public void setBehindOffsetRes(int resID) {   
-          int i = (int) getContext().getResources().getDimension(resID);   
-          setBehindOffset(i);   
-      }   
-     
-      /**  
-       * Sets the above offset.  
-       *   
-       * @param i  
-       *            the new above offset, in pixels  
-       */   
-      public void setAboveOffset(int i) {   
-          mViewAbove.setAboveOffset(i);   
-      }   
-     
-      /**  
-       * Sets the above offset.  
-       *   
-       * @param resID  
-       *            The dimension resource id to be set as the above offset.  
-       */   
-      public void setAboveOffsetRes(int resID) {   
-          int i = (int) getContext().getResources().getDimension(resID);   
-          setAboveOffset(i);   
-      }   
-     
-      /**  
-       * Sets the behind width.  
-       *   
-       * @param i  
-       *            The width the Sliding Menu will open to, in pixels  
-       */   
-      @SuppressWarnings("deprecation")   
-      public void setBehindWidth(int i) {   
-          int width;   
-          Display display = ((WindowManager) getContext().getSystemService(   
-                  Context.WINDOW_SERVICE)).getDefaultDisplay();   
-          try {   
-              Class<?> cls = Display.class;   
-              Class<?>[] parameterTypes = { Point.class };   
-              Point parameter = new Point();   
-              Method method = cls.getMethod("getSize", parameterTypes);   
-              method.invoke(display, parameter);   
-              width = parameter.x;   
-          } catch (Exception e) {   
-              width = display.getWidth();   
-          }   
-          setBehindOffset(width - i);   
-      }   
-     
-      /**  
-       * Sets the behind width.  
-       *   
-       * @param res  
-       *            The dimension resource id to be set as the behind width  
-       *            offset. The menu, when open, will open this wide.  
-       */   
-      public void setBehindWidthRes(int res) {   
-          int i = (int) getContext().getResources().getDimension(res);   
-          setBehindWidth(i);   
-      }   
-     
-      /**  
-       * Gets the behind scroll scale.  
-       *   
-       * @return The scale of the parallax scroll  
-       */   
-      public float getBehindScrollScale() {   
-          return mViewBehind.getScrollScale();   
-      }   
-     
-      /**  
-       * Gets the touch mode margin threshold  
-       *   
-       * @return the touch mode margin threshold  
-       */   
-      public int getTouchmodeMarginThreshold() {   
-          return mViewBehind.getMarginThreshold();   
-      }   
-     
-      /**  
-       * Set the touch mode margin threshold  
-       *   
-       * @param touchmodeMarginThreshold  
-       */   
-      public void setTouchmodeMarginThreshold(int touchmodeMarginThreshold) {   
-          mViewBehind.setMarginThreshold(touchmodeMarginThreshold);   
-      }   
-     
-      /**  
-       * Sets the behind scroll scale.  
-       *   
-       * @param f  
-       *            The scale of the parallax scroll (i.e. 1.0f scrolls 1 pixel  
-       *            for every 1 pixel that the above view scrolls and 0.0f scrolls  
-       *            0 pixels)  
-       */   
-      public void setBehindScrollScale(float f) {   
-          if (f < 0 && f > 1)   
-              throw new IllegalStateException(   
-                      "ScrollScale must be between 0 and 1");   
-          mViewBehind.setScrollScale(f);   
-      }   
-     
-      /**  
-       * Sets the behind canvas transformer.  
-       *   
-       * @param t  
-       *            the new behind canvas transformer  
-       */   
-      public void setBehindCanvasTransformer(CanvasTransformer t) {   
-          mViewBehind.setCanvasTransformer(t);   
-      }   
-     
-      /**  
-       * 设置右侧视图的转场动画  
-       *   
-       * @param t  
-       *            the new above canvas transformer  
-       */   
-      public void setAboveCanvasTransformer(CanvasTransformer t) {   
-          mViewAbove.setCanvasTransformer(t);   
-      }   
-     
-      /**  
-       * Gets the touch mode above.  
-       *   
-       * @return the touch mode above  
-       */   
-      public int getTouchModeAbove() {   
-          return mViewAbove.getTouchMode();   
-      }   
-     
-      /**  
-       * Controls whether the SlidingMenu can be opened with a swipe gesture.  
-       * Options are {@link #TOUCHMODE_MARGIN TOUCHMODE_MARGIN},  
-       * {@link #TOUCHMODE_FULLSCREEN TOUCHMODE_FULLSCREEN}, or  
-       * {@link #TOUCHMODE_NONE TOUCHMODE_NONE}  
-       *   
-       * @param i  
-       *            the new touch mode  
-       */   
-      public void setTouchModeAbove(int i) {   
-          if (i != TOUCHMODE_FULLSCREEN && i != TOUCHMODE_MARGIN   
-                  && i != TOUCHMODE_NONE) {   
-              throw new IllegalStateException(   
-                      "TouchMode must be set to either"   
-                              + "TOUCHMODE_FULLSCREEN or TOUCHMODE_MARGIN or TOUCHMODE_NONE.");   
-          }   
-          mViewAbove.setTouchMode(i);   
-      }   
-     
-      /**  
-       * Controls whether the SlidingMenu can be opened with a swipe gesture.  
-       * Options are {@link #TOUCHMODE_MARGIN TOUCHMODE_MARGIN},  
-       * {@link #TOUCHMODE_FULLSCREEN TOUCHMODE_FULLSCREEN}, or  
-       * {@link #TOUCHMODE_NONE TOUCHMODE_NONE}  
-       *   
-       * @param i  
-       *            the new touch mode  
-       */   
-      public void setTouchModeBehind(int i) {   
-          if (i != TOUCHMODE_FULLSCREEN && i != TOUCHMODE_MARGIN   
-                  && i != TOUCHMODE_NONE) {   
-              throw new IllegalStateException(   
-                      "TouchMode must be set to either"   
-                              + "TOUCHMODE_FULLSCREEN or TOUCHMODE_MARGIN or TOUCHMODE_NONE.");   
-          }   
-          mViewBehind.setTouchMode(i);   
-      }   
-     
-      /**  
-       * Sets the shadow drawable.  
-       *   
-       * @param resId  
-       *            the resource ID of the new shadow drawable  
-       */   
-      public void setShadowDrawable(int resId) {   
-          setShadowDrawable(getContext().getResources().getDrawable(resId));   
-      }   
-     
-      /**  
-       * Sets the shadow drawable.  
-       *   
-       * @param d  
-       *            the new shadow drawable  
-       */   
-      public void setShadowDrawable(Drawable d) {   
-          mViewBehind.setShadowDrawable(d);   
-      }   
-     
-      /**  
-       * Sets the secondary (right) shadow drawable.  
-       *   
-       * @param resId  
-       *            the resource ID of the new shadow drawable  
-       */   
-      public void setSecondaryShadowDrawable(int resId) {   
-          setSecondaryShadowDrawable(getContext().getResources().getDrawable(   
-                  resId));   
-      }   
-     
-      /**  
-       * Sets the secondary (right) shadow drawable.  
-       *   
-       * @param d  
-       *            the new shadow drawable  
-       */   
-      public void setSecondaryShadowDrawable(Drawable d) {   
-          mViewBehind.setSecondaryShadowDrawable(d);   
-      }   
-     
-      /**  
-       * Sets the shadow width.  
-       *   
-       * @param resId  
-       *            The dimension resource id to be set as the shadow width.  
-       */   
-      public void setShadowWidthRes(int resId) {   
-          setShadowWidth((int) getResources().getDimension(resId));   
-      }   
-     
-      /**  
-       * Sets the shadow width.  
-       *   
-       * @param pixels  
-       *            the new shadow width, in pixels  
-       */   
-      public void setShadowWidth(int pixels) {   
-          mViewBehind.setShadowWidth(pixels);   
-      }   
-     
-      /**  
-       * Enables or disables the SlidingMenu‘s fade in and out  
-       *   
-       * @param b  
-       *            true to enable fade, false to disable it  
-       */   
-      public void setFadeEnabled(boolean b) {   
-          mViewBehind.setFadeEnabled(b);   
-      }   
-     
-      /**  
-       * Sets how much the SlidingMenu fades in and out. Fade must be enabled, see  
-       * {@link #setFadeEnabled(boolean) setFadeEnabled(boolean)}  
-       *   
-       * @param f  
-       *            the new fade degree, between 0.0f and 1.0f  
-       */   
-      public void setFadeDegree(float f) {   
-          mViewBehind.setFadeDegree(f);   
-      }   
-     
-      /**  
-       * Enables or disables whether the selector is drawn  
-       *   
-       * @param b  
-       *            true to draw the selector, false to not draw the selector  
-       */   
-      public void setSelectorEnabled(boolean b) {   
-          mViewBehind.setSelectorEnabled(true);   
-      }   
-     
-      /**  
-       * Sets the selected view. The selector will be drawn here  
-       *   
-       * @param v  
-       *            the new selected view  
-       */   
-      public void setSelectedView(View v) {   
-          mViewBehind.setSelectedView(v);   
-      }   
-     
-      /**  
-       * Sets the selector drawable.  
-       *   
-       * @param res  
-       *            a resource ID for the selector drawable  
-       */   
-      public void setSelectorDrawable(int res) {   
-          mViewBehind.setSelectorBitmap(BitmapFactory.decodeResource(   
-                  getResources(), res));   
-      }   
-     
-      /**  
-       * Sets the selector drawable.  
-       *   
-       * @param b  
-       *            the new selector bitmap  
-       */   
-      public void setSelectorBitmap(Bitmap b) {   
-          mViewBehind.setSelectorBitmap(b);   
-      }   
-     
-      /**  
-       * Add a View ignored by the Touch Down event when mode is Fullscreen  
-       *   
-       * @param v  
-       *            a view to be ignored  
-       */   
-      public void addIgnoredView(View v) {   
-          mViewAbove.addIgnoredView(v);   
-      }   
-     
-      /**  
-       * Remove a View ignored by the Touch Down event when mode is Fullscreen  
-       *   
-       * @param v  
-       *            a view not wanted to be ignored anymore  
-       */   
-      public void removeIgnoredView(View v) {   
-          mViewAbove.removeIgnoredView(v);   
-      }   
-     
-      /**  
-       * Clear the list of Views ignored by the Touch Down event when mode is  
-       * Fullscreen  
-       */   
-      public void clearIgnoredViews() {   
-          mViewAbove.clearIgnoredViews();   
-      }   
-     
-      /**  
-       * Sets the OnOpenListener. {@link OnOpenListener#onOpen()  
-       * OnOpenListener.onOpen()} will be called when the SlidingMenu is opened  
-       *   
-       * @param listener  
-       *            the new OnOpenListener  
-       */   
-      public void setOnOpenListener(OnOpenListener listener) {   
-          // mViewAbove.setOnOpenListener(listener);   
-          mOpenListener = listener;   
-      }   
-     
-      /**  
-       * Sets the OnOpenListner for secondary menu {@link OnOpenListener#onOpen()  
-       * OnOpenListener.onOpen()} will be called when the secondary SlidingMenu is  
-       * opened  
-       *   
-       * @param listener  
-       *            the new OnOpenListener  
-       */   
-     
-      public void setSecondaryOnOpenListner(OnOpenListener listener) {   
-          mSecondaryOpenListner = listener;   
-      }   
-     
-      /**  
-       * Sets the OnCloseListener. {@link OnCloseListener#onClose()  
-       * OnCloseListener.onClose()} will be called when any one of the SlidingMenu  
-       * is closed  
-       *   
-       * @param listener  
-       *            the new setOnCloseListener  
-       */   
-      public void setOnCloseListener(OnCloseListener listener) {   
-          // mViewAbove.setOnCloseListener(listener);   
-          mCloseListener = listener;   
-      }   
-     
-      /**  
-       * Sets the OnOpenedListener. {@link OnOpenedListener#onOpened()  
-       * OnOpenedListener.onOpened()} will be called after the SlidingMenu is  
-       * opened  
-       *   
-       * @param listener  
-       *            the new OnOpenedListener  
-       */   
-      public void setOnOpenedListener(OnOpenedListener listener) {   
-          mViewAbove.setOnOpenedListener(listener);   
-      }   
-     
-      /**  
-       * Sets the OnClosedListener. {@link OnClosedListener#onClosed()  
-       * OnClosedListener.onClosed()} will be called after the SlidingMenu is  
-       * closed  
-       *   
-       * @param listener  
-       *            the new OnClosedListener  
-       */   
-      public void setOnClosedListener(OnClosedListener listener) {   
-          mViewAbove.setOnClosedListener(listener);   
-      }   
-     
-      public static class SavedState extends BaseSavedState {   
-     
-          private final int mItem;   
-     
-          public SavedState(Parcelable superState, int item) {   
-              super(superState);   
-              mItem = item;   
-          }   
-     
-          private SavedState(Parcel in) {   
-              super(in);   
-              mItem = in.readInt();   
-          }   
-     
-          public int getItem() {   
-              return mItem;   
-          }   
-     
-          /*  
-           * (non-Javadoc)  
-           *   
-           * @see android.view.AbsSavedState#writeToParcel(android.os.Parcel, int)  
-           */   
-          public void writeToParcel(Parcel out, int flags) {   
-              super.writeToParcel(out, flags);   
-              out.writeInt(mItem);   
-          }   
-     
-          public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {   
-              public SavedState createFromParcel(Parcel in) {   
-                  return new SavedState(in);   
-              }   
-     
-              public SavedState[] newArray(int size) {   
-                  return new SavedState[size];   
-              }   
-          };   
-     
-      }   
-     
-      /*  
-       * (non-Javadoc)  
-       *   
-       * @see android.view.View#onSaveInstanceState()  
-       */   
-      @Override   
-      protected Parcelable onSaveInstanceState() {   
-          Parcelable superState = super.onSaveInstanceState();   
-          SavedState ss = new SavedState(superState, mViewAbove.getCurrentItem());   
-          return ss;   
-      }   
-     
-      /*  
-       * (non-Javadoc)  
-       *   
-       * @see android.view.View#onRestoreInstanceState(android.os.Parcelable)  
-       */   
-      @Override   
-      protected void onRestoreInstanceState(Parcelable state) {   
-          SavedState ss = (SavedState) state;   
-          super.onRestoreInstanceState(ss.getSuperState());   
-          mViewAbove.setCurrentItem(ss.getItem());   
-      }   
-     
-      /*  
-       * (non-Javadoc)  
-       *   
-       * @see android.view.ViewGroup#fitSystemWindows(android.graphics.Rect)  
-       */   
-      @SuppressLint("NewApi")   
-      @Override   
-      protected boolean fitSystemWindows(Rect insets) {   
-          int leftPadding = insets.left;   
-          int rightPadding = insets.right;   
-          int topPadding = insets.top;   
-          int bottomPadding = insets.bottom;   
-          if (!mActionbarOverlay) {   
-              Log.v(TAG, "setting padding!");   
-              setPadding(leftPadding, topPadding, rightPadding, bottomPadding);   
-          }   
-          return true;   
-      }   
-     
-      @TargetApi(Build.VERSION_CODES.HONEYCOMB)   
-      public void manageLayers(float percentOpen) {   
-          if (Build.VERSION.SDK_INT < 11)   
-              return;   
-     
-          boolean layer = percentOpen > 0.0f && percentOpen < 1.0f;   
-          final int layerType = layer ? View.LAYER_TYPE_HARDWARE   
-                  : View.LAYER_TYPE_NONE;   
-     
-          if (layerType != getContent().getLayerType()) {   
-              getHandler().post(new Runnable() {   
-                  public void run() {   
-                      Log.v(TAG, "changing layerType. hardware? "   
-                              + (layerType == View.LAYER_TYPE_HARDWARE));   
-                      getContent().setLayerType(layerType, null);   
-                      getMenu().setLayerType(layerType, null);   
-                      if (getSecondaryMenu() != null) {   
-                          getSecondaryMenu().setLayerType(layerType, null);   
-                      }   
-                  }   
-              });   
-          }   
-      }   
-     
-  }   
  
 
  
  
  -  public class CustomViewAbove extends ViewGroup {   
-     
-      private static final String TAG = "CustomViewAbove";   
-      private static final boolean DEBUG = false;   
-     
-      private static final boolean USE_CACHE = false;   
-     
-      private static final int MAX_SETTLE_DURATION = 600; // ms   
-      private static final int MIN_DISTANCE_FOR_FLING = 25; // dips   
-     
-      private static final Interpolator sInterpolator = new Interpolator() {   
-          public float getInterpolation(float t) {   
-              t -= 1.0f;   
-              return t * t * t * t * t + 1.0f;   
-          }   
-      };   
-     
-      private View mContent;   
-     
-      private int mCurItem;   
-      private Scroller mScroller;   
-     
-      private boolean mScrollingCacheEnabled;   
-     
-      private boolean mScrolling;   
-     
-      private boolean mIsBeingDragged;   
-      private boolean mIsUnableToDrag;   
-      private int mTouchSlop;   
-      private float mInitialMotionX;   
-      /**  
-       * Position of the last motion event.  
-       */   
-      private float mLastMotionX;   
-      private float mLastMotionY;   
-      /**  
-       * ID of the active pointer. This is used to retain consistency during  
-       * drags/flings if multiple pointers are used.  
-       */   
-      protected int mActivePointerId = INVALID_POINTER;   
-      /**  
-       * Sentinel value for no current active pointer.  
-       * Used by {@link #mActivePointerId}.  
-       */   
-      private static final int INVALID_POINTER = -1;   
-          /** 保存转场动画的变量*/   
-      private CanvasTransformer mTransformer;   
-         
-      /**  
-       * Determines speed during touch scrolling  
-       */   
-      protected VelocityTracker mVelocityTracker;   
-      private int mMinimumVelocity;   
-      protected int mMaximumVelocity;   
-      private int mFlingDistance;   
-     
-      private CustomViewBehind mViewBehind;   
-      //  private int mMode;   
-      private boolean mEnabled = true;   
-     
-      private OnPageChangeListener mOnPageChangeListener;   
-      private OnPageChangeListener mInternalPageChangeListener;   
-     
-      //  private OnCloseListener mCloseListener;   
-      //  private OnOpenListener mOpenListener;   
-      private OnClosedListener mClosedListener;   
-      private OnOpenedListener mOpenedListener;   
-     
-      private List<View> mIgnoredViews = new ArrayList<View>();   
-     
-      //  private int mScrollState = SCROLL_STATE_IDLE;   
-     
-      /**  
-       * Callback interface for responding to changing state of the selected page.  
-       */   
-      public interface OnPageChangeListener {   
-     
-          /**  
-           * This method will be invoked when the current page is scrolled, either as part  
-           * of a programmatically initiated smooth scroll or a user initiated touch scroll.  
-           *  
-           * @param position Position index of the first page currently being displayed.  
-           *                 Page position+1 will be visible if positionOffset is nonzero.  
-           * @param positionOffset Value from [0, 1) indicating the offset from the page at position.  
-           * @param positionOffsetPixels Value in pixels indicating the offset from position.  
-           */   
-          public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);   
-     
-          /**  
-           * This method will be invoked when a new page becomes selected. Animation is not  
-           * necessarily complete.  
-           *  
-           * @param position Position index of the new selected page.  
-           */   
-          public void onPageSelected(int position);   
-     
-      }   
-     
-      /**  
-       * Simple implementation of the {@link OnPageChangeListener} interface with stub  
-       * implementations of each method. Extend this if you do not intend to override  
-       * every method of {@link OnPageChangeListener}.  
-       */   
-      public static class SimpleOnPageChangeListener implements OnPageChangeListener {   
-     
-          public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {   
-              // This space for rent   
-          }   
-     
-          public void onPageSelected(int position) {   
-              // This space for rent   
-          }   
-     
-          public void onPageScrollStateChanged(int state) {   
-              // This space for rent   
-          }   
-     
-      }   
-     
-      public CustomViewAbove(Context context) {   
-          this(context, null);   
-      }   
-     
-      public CustomViewAbove(Context context, AttributeSet attrs) {   
-          super(context, attrs);   
-          initCustomViewAbove();   
-      }   
-     
-      void initCustomViewAbove() {   
-          setWillNotDraw(false);   
-          setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);   
-          setFocusable(true);   
-          final Context context = getContext();   
-          mScroller = new Scroller(context, sInterpolator);   
-          final ViewConfiguration configuration = ViewConfiguration.get(context);   
-          mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);   
-          mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();   
-          mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();   
-          setInternalPageChangeListener(new SimpleOnPageChangeListener() {   
-              public void onPageSelected(int position) {   
-                  if (mViewBehind != null) {   
-                      switch (position) {   
-                      case 0:   
-                      case 2:   
-                          mViewBehind.setChildrenEnabled(true);   
-                          break;   
-                      case 1:   
-                          mViewBehind.setChildrenEnabled(false);   
-                          break;   
-                      }   
-                  }   
-              }   
-          });   
-     
-          final float density = context.getResources().getDisplayMetrics().density;   
-          mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density);   
-      }   
-     
-      /**  
-       * Set the currently selected page. If the CustomViewPager has already been through its first  
-       * layout there will be a smooth animated transition between the current item and the  
-       * specified item.  
-       *  
-       * @param item Item index to select  
-       */   
-      public void setCurrentItem(int item) {   
-          setCurrentItemInternal(item, true, false);   
-      }   
-     
-      /**  
-       * Set the currently selected page.  
-       *  
-       * @param item Item index to select  
-       * @param smoothScroll True to smoothly scroll to the new item, false to transition immediately  
-       */   
-      public void setCurrentItem(int item, boolean smoothScroll) {   
-          setCurrentItemInternal(item, smoothScroll, false);   
-      }   
-     
-      public int getCurrentItem() {   
-          return mCurItem;   
-      }   
-     
-      void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) {   
-          setCurrentItemInternal(item, smoothScroll, always, 0);   
-      }   
-     
-      void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {   
-          if (!always && mCurItem == item) {   
-              setScrollingCacheEnabled(false);   
-              return;   
-          }   
-     
-          item = mViewBehind.getMenuPage(item);   
-     
-          final boolean dispatchSelected = mCurItem != item;   
-          mCurItem = item;   
-          final int destX = getDestScrollX(mCurItem);   
-          if (dispatchSelected && mOnPageChangeListener != null) {   
-              mOnPageChangeListener.onPageSelected(item);   
-          }   
-          if (dispatchSelected && mInternalPageChangeListener != null) {   
-              mInternalPageChangeListener.onPageSelected(item);   
-          }   
-          if (smoothScroll) {   
-              smoothScrollTo(destX, 0, velocity);   
-          } else {   
-              completeScroll();   
-              scrollTo(destX, 0);   
-          }   
-      }   
-     
-      /**  
-       * Set a listener that will be invoked whenever the page changes or is incrementally  
-       * scrolled. See {@link OnPageChangeListener}.  
-       *  
-       * @param listener Listener to set  
-       */   
-      public void setOnPageChangeListener(OnPageChangeListener listener) {   
-          mOnPageChangeListener = listener;   
-      }   
-      /*  
-      public void setOnOpenListener(OnOpenListener l) {  
-          mOpenListener = l;  
-      }  
-    
-      public void setOnCloseListener(OnCloseListener l) {  
-          mCloseListener = l;  
-      }  
-       */   
-      public void setOnOpenedListener(OnOpenedListener l) {   
-          mOpenedListener = l;   
-      }   
-     
-      public void setOnClosedListener(OnClosedListener l) {   
-          mClosedListener = l;   
-      }   
-     
-      /**  
-       * Set a separate OnPageChangeListener for internal use by the support library.  
-       *  
-       * @param listener Listener to set  
-       * @return The old listener that was set, if any.  
-       */   
-      OnPageChangeListener setInternalPageChangeListener(OnPageChangeListener listener) {   
-          OnPageChangeListener oldListener = mInternalPageChangeListener;   
-          mInternalPageChangeListener = listener;   
-          return oldListener;   
-      }   
-     
-      public void addIgnoredView(View v) {   
-          if (!mIgnoredViews.contains(v)) {   
-              mIgnoredViews.add(v);   
-          }   
-      }   
-     
-      public void removeIgnoredView(View v) {   
-          mIgnoredViews.remove(v);   
-      }   
-     
-      public void clearIgnoredViews() {   
-          mIgnoredViews.clear();   
-      }   
-     
-      // We want the duration of the page snap animation to be influenced by the distance that   
-      // the screen has to travel, however, we don‘t want this duration to be effected in a   
-      // purely linear fashion. Instead, we use this method to moderate the effect that the distance   
-      // of travel has on the overall snap duration.   
-      float distanceInfluenceForSnapDuration(float f) {   
-          f -= 0.5f; // center the values about 0.   
-          f *= 0.3f * Math.PI / 2.0f;   
-          return (float) FloatMath.sin(f);   
-      }   
-     
-      public int getDestScrollX(int page) {   
-          switch (page) {   
-          case 0:   
-          case 2:   
-              return mViewBehind.getMenuLeft(mContent, page);   
-          case 1:   
-              return mContent.getLeft();   
-          }   
-          return 0;   
-      }   
-     
-      private int getLeftBound() {   
-          return mViewBehind.getAbsLeftBound(mContent);   
-      }   
-     
-      private int getRightBound() {   
-          return mViewBehind.getAbsRightBound(mContent);   
-      }   
-     
-      public int getContentLeft() {   
-          return mContent.getLeft() + mContent.getPaddingLeft();   
-      }   
-     
-      public boolean isMenuOpen() {   
-          return mCurItem == 0 || mCurItem == 2;   
-      }   
-     
-      private boolean isInIgnoredView(MotionEvent ev) {   
-          Rect rect = new Rect();   
-          for (View v : mIgnoredViews) {   
-              v.getHitRect(rect);   
-              if (rect.contains((int)ev.getX(), (int)ev.getY())) return true;   
-          }   
-          return false;   
-      }   
-     
-      public int getBehindWidth() {   
-          if (mViewBehind == null) {   
-              return 0;   
-          } else {   
-              return mViewBehind.getBehindWidth();   
-          }   
-      }   
-     
-      public int getChildWidth(int i) {   
-          switch (i) {   
-          case 0:   
-              return getBehindWidth();   
-          case 1:   
-              return mContent.getWidth();   
-          default:   
-              return 0;   
-          }   
-      }   
-     
-      public boolean isSlidingEnabled() {   
-          return mEnabled;   
-      }   
-     
-      public void setSlidingEnabled(boolean b) {   
-          mEnabled = b;   
-      }   
-     
-      /**  
-       * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.  
-       *  
-       * @param x the number of pixels to scroll by on the X axis  
-       * @param y the number of pixels to scroll by on the Y axis  
-       */   
-      void smoothScrollTo(int x, int y) {   
-          smoothScrollTo(x, y, 0);   
-      }   
-     
-      /**  
-       * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.  
-       *  
-       * @param x the number of pixels to scroll by on the X axis  
-       * @param y the number of pixels to scroll by on the Y axis  
-       * @param velocity the velocity associated with a fling, if applicable. (0 otherwise)  
-       */   
-      void smoothScrollTo(int x, int y, int velocity) {   
-          if (getChildCount() == 0) {   
-              // Nothing to do.   
-              setScrollingCacheEnabled(false);   
-              return;   
-          }   
-          int sx = getScrollX();   
-          int sy = getScrollY();   
-          int dx = x - sx;   
-          int dy = y - sy;   
-          if (dx == 0 && dy == 0) {   
-              completeScroll();   
-              if (isMenuOpen()) {   
-                  if (mOpenedListener != null)   
-                      mOpenedListener.onOpened();   
-              } else {   
-                  if (mClosedListener != null)   
-                      mClosedListener.onClosed();   
-              }   
-              return;   
-          }   
-     
-          setScrollingCacheEnabled(true);   
-          mScrolling = true;   
-     
-          final int width = getBehindWidth();   
-          final int halfWidth = width / 2;   
-          final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dx) / width);   
-          final float distance = halfWidth + halfWidth *   
-                  distanceInfluenceForSnapDuration(distanceRatio);   
-     
-          int duration = 0;   
-          velocity = Math.abs(velocity);   
-          if (velocity > 0) {   
-              duration = 4 * Math.round(1000 * Math.abs(distance / velocity));   
-          } else {   
-              final float pageDelta = (float) Math.abs(dx) / width;   
-              duration = (int) ((pageDelta + 1) * 100);   
-              duration = MAX_SETTLE_DURATION;   
-          }   
-          duration = Math.min(duration, MAX_SETTLE_DURATION);   
-     
-          mScroller.startScroll(sx, sy, dx, dy, duration);   
-          invalidate();   
-      }   
-     
-      public void setContent(View v) {   
-          if (mContent != null)    
-              this.removeView(mContent);   
-          mContent = v;   
-          addView(mContent);   
-      }   
-     
-      public View getContent() {   
-          return mContent;   
-      }   
-     
-      public void setCustomViewBehind(CustomViewBehind cvb) {   
-          mViewBehind = cvb;   
-      }   
-     
-      @Override   
-      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   
-     
-          int width = getDefaultSize(0, widthMeasureSpec);   
-          int height = getDefaultSize(0, heightMeasureSpec);   
-          setMeasuredDimension(width, height);   
-     
-          final int contentWidth = getChildMeasureSpec(widthMeasureSpec, 0, width);   
-          final int contentHeight = getChildMeasureSpec(heightMeasureSpec, 0, height);   
-          mContent.measure(contentWidth, contentHeight);   
-      }   
-     
-      @Override   
-      protected void onSizeChanged(int w, int h, int oldw, int oldh) {   
-          super.onSizeChanged(w, h, oldw, oldh);   
-          // Make sure scroll position is set correctly.   
-          if (w != oldw) {   
-              // [ChrisJ] - This fixes the onConfiguration change for orientation issue..   
-              // maybe worth having a look why the recomputeScroll pos is screwing   
-              // up?   
-              completeScroll();   
-              scrollTo(getDestScrollX(mCurItem), getScrollY());   
-          }   
-      }   
-     
-      @Override   
-      protected void onLayout(boolean changed, int l, int t, int r, int b) {   
-          final int width = r - l;   
-          final int height = b - t;   
-          mContent.layout(0, 0, width, height);   
-      }   
-     
-      public void setAboveOffset(int i) {   
-          //      RelativeLayout.LayoutParams params = ((RelativeLayout.LayoutParams)mContent.getLayoutParams());   
-          //      params.setMargins(i, params.topMargin, params.rightMargin, params.bottomMargin);   
-          mContent.setPadding(i, mContent.getPaddingTop(),    
-                  mContent.getPaddingRight(), mContent.getPaddingBottom());   
-      }   
-     
-     
-      @Override   
-      public void computeScroll() {   
-          if (!mScroller.isFinished()) {   
-              if (mScroller.computeScrollOffset()) {   
-                  int oldX = getScrollX();   
-                  int oldY = getScrollY();   
-                  int x = mScroller.getCurrX();   
-                  int y = mScroller.getCurrY();   
-     
-                  if (oldX != x || oldY != y) {   
-                      scrollTo(x, y);   
-                      pageScrolled(x);   
-                  }   
-     
-                  // Keep on drawing until the animation has finished.   
-                  invalidate();   
-                  return;   
-              }   
-          }   
-     
-          // Done with scroll, clean up state.   
-          completeScroll();   
-      }   
-     
-      private void pageScrolled(int xpos) {   
-          final int widthWithMargin = getWidth();   
-          final int position = xpos / widthWithMargin;   
-          final int offsetPixels = xpos % widthWithMargin;   
-          final float offset = (float) offsetPixels / widthWithMargin;   
-     
-          onPageScrolled(position, offset, offsetPixels);   
-      }   
-     
-      /**  
-       * This method will be invoked when the current page is scrolled, either as part  
-       * of a programmatically initiated smooth scroll or a user initiated touch scroll.  
-       * If you override this method you must call through to the superclass implementation  
-       * (e.g. super.onPageScrolled(position, offset, offsetPixels)) before onPageScrolled  
-       * returns.  
-       *  
-       * @param position Position index of the first page currently being displayed.  
-       *                 Page position+1 will be visible if positionOffset is nonzero.  
-       * @param offset Value from [0, 1) indicating the offset from the page at position.  
-       * @param offsetPixels Value in pixels indicating the offset from position.  
-       */   
-      protected void onPageScrolled(int position, float offset, int offsetPixels) {   
-          if (mOnPageChangeListener != null) {   
-              mOnPageChangeListener.onPageScrolled(position, offset, offsetPixels);   
-          }   
-          if (mInternalPageChangeListener != null) {   
-              mInternalPageChangeListener.onPageScrolled(position, offset, offsetPixels);   
-          }   
-      }   
-     
-      private void completeScroll() {   
-          boolean needPopulate = mScrolling;   
-          if (needPopulate) {   
-              // Done with scroll, no longer want to cache view drawing.   
-              setScrollingCacheEnabled(false);   
-              mScroller.abortAnimation();   
-              int oldX = getScrollX();   
-              int oldY = getScrollY();   
-              int x = mScroller.getCurrX();   
-              int y = mScroller.getCurrY();   
-              if (oldX != x || oldY != y) {   
-                  scrollTo(x, y);   
-              }   
-              if (isMenuOpen()) {   
-                  if (mOpenedListener != null)   
-                      mOpenedListener.onOpened();   
-              } else {   
-                  if (mClosedListener != null)   
-                      mClosedListener.onClosed();   
-              }   
-          }   
-          mScrolling = false;   
-      }   
-     
-      protected int mTouchMode = SlidingMenu.TOUCHMODE_MARGIN;   
-     
-      public void setTouchMode(int i) {   
-          mTouchMode = i;   
-      }   
-     
-      public int getTouchMode() {   
-          return mTouchMode;   
-      }   
-     
-      private boolean thisTouchAllowed(MotionEvent ev) {   
-          int x = (int) (ev.getX() + mScrollX);   
-          if (isMenuOpen()) {   
-              return mViewBehind.menuOpenTouchAllowed(mContent, mCurItem, x);   
-          } else {   
-              switch (mTouchMode) {   
-              case SlidingMenu.TOUCHMODE_FULLSCREEN:   
-                  return !isInIgnoredView(ev);   
-              case SlidingMenu.TOUCHMODE_NONE:   
-                  return false;   
-              case SlidingMenu.TOUCHMODE_MARGIN:   
-                  return mViewBehind.marginTouchAllowed(mContent, x);   
-              }   
-          }   
-          return false;   
-      }   
-     
-      private boolean thisSlideAllowed(float dx) {   
-          boolean allowed = false;   
-          if (isMenuOpen()) {   
-              allowed = mViewBehind.menuOpenSlideAllowed(dx);   
-          } else {   
-              allowed = mViewBehind.menuClosedSlideAllowed(dx);   
-          }   
-          if (DEBUG)   
-              Log.v(TAG, "this slide allowed " + allowed + " dx: " + dx);   
-          return allowed;   
-      }   
-     
-      private int getPointerIndex(MotionEvent ev, int id) {   
-          int activePointerIndex = MotionEventCompat.findPointerIndex(ev, id);   
-          if (activePointerIndex == -1)   
-              mActivePointerId = INVALID_POINTER;   
-          return activePointerIndex;   
-      }   
-     
-      private boolean mQuickReturn = false;   
-     
-      @Override   
-      public boolean onInterceptTouchEvent(MotionEvent ev) {   
-     
-          if (!mEnabled)   
-              return false;   
-     
-          final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;   
-     
-          if (DEBUG)   
-              if (action == MotionEvent.ACTION_DOWN)   
-                  Log.v(TAG, "Received ACTION_DOWN");   
-     
-          if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP   
-                  || (action != MotionEvent.ACTION_DOWN && mIsUnableToDrag)) {   
-              endDrag();   
-              return false;   
-          }   
-     
-          switch (action) {   
-          case MotionEvent.ACTION_MOVE:   
-              determineDrag(ev);   
-              break;   
-          case MotionEvent.ACTION_DOWN:   
-              int index = MotionEventCompat.getActionIndex(ev);   
-              mActivePointerId = MotionEventCompat.getPointerId(ev, index);   
-              if (mActivePointerId == INVALID_POINTER)   
-                  break;   
-              mLastMotionX = mInitialMotionX = MotionEventCompat.getX(ev, index);   
-              mLastMotionY = MotionEventCompat.getY(ev, index);   
-              if (thisTouchAllowed(ev)) {   
-                  mIsBeingDragged = false;   
-                  mIsUnableToDrag = false;   
-                  if (isMenuOpen() && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) {   
-                      mQuickReturn = true;   
-                  }   
-              } else {   
-                  mIsUnableToDrag = true;   
-              }   
-              break;   
-          case MotionEventCompat.ACTION_POINTER_UP:   
-              onSecondaryPointerUp(ev);   
-              break;   
-          }   
-     
-          if (!mIsBeingDragged) {   
-              if (mVelocityTracker == null) {   
-                  mVelocityTracker = VelocityTracker.obtain();   
-              }   
-              mVelocityTracker.addMovement(ev);   
-          }   
-          return mIsBeingDragged || mQuickReturn;   
-      }   
-     
-     
-      @Override   
-      public boolean onTouchEvent(MotionEvent ev) {   
-     
-          if (!mEnabled)   
-              return false;   
-     
-          if (!mIsBeingDragged && !thisTouchAllowed(ev))   
-              return false;   
-     
-          //      if (!mIsBeingDragged && !mQuickReturn)   
-          //          return false;   
-     
-          final int action = ev.getAction();   
-     
-          if (mVelocityTracker == null) {   
-              mVelocityTracker = VelocityTracker.obtain();   
-          }   
-          mVelocityTracker.addMovement(ev);   
-     
-          switch (action & MotionEventCompat.ACTION_MASK) {   
-          case MotionEvent.ACTION_DOWN:   
-              /*  
-               * If being flinged and user touches, stop the fling. isFinished  
-               * will be false if being flinged.  
-               */   
-              completeScroll();   
-     
-              // Remember where the motion event started   
-              int index = MotionEventCompat.getActionIndex(ev);   
-              mActivePointerId = MotionEventCompat.getPointerId(ev, index);   
-              mLastMotionX = mInitialMotionX = ev.getX();   
-              break;   
-          case MotionEvent.ACTION_MOVE:   
-              if (!mIsBeingDragged) {    
-                  determineDrag(ev);   
-                  if (mIsUnableToDrag)   
-                      return false;   
-              }   
-              if (mIsBeingDragged) {   
-                  // Scroll to follow the motion event   
-                  final int activePointerIndex = getPointerIndex(ev, mActivePointerId);   
-                  if (mActivePointerId == INVALID_POINTER)   
-                      break;   
-                  final float x = MotionEventCompat.getX(ev, activePointerIndex);   
-                  final float deltaX = mLastMotionX - x;   
-                  mLastMotionX = x;   
-                  float oldScrollX = getScrollX();   
-                  float scrollX = oldScrollX + deltaX;   
-                  final float leftBound = getLeftBound();   
-                  final float rightBound = getRightBound();   
-                  if (scrollX < leftBound) {   
-                      scrollX = leftBound;   
-                  } else if (scrollX > rightBound) {   
-                      scrollX = rightBound;   
-                  }   
-                  // Don‘t lose the rounded component   
-                  mLastMotionX += scrollX - (int) scrollX;   
-                  scrollTo((int) scrollX, getScrollY());   
-                  pageScrolled((int) scrollX);   
-              }   
-              break;   
-          case MotionEvent.ACTION_UP:   
-              if (mIsBeingDragged) {   
-                  final VelocityTracker velocityTracker = mVelocityTracker;   
-                  velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);   
-                  int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(   
-                          velocityTracker, mActivePointerId);   
-                  final int scrollX = getScrollX();   
-                  final float pageOffset = (float) (scrollX - getDestScrollX(mCurItem)) / getBehindWidth();   
-                  final int activePointerIndex = getPointerIndex(ev, mActivePointerId);   
-                  if (mActivePointerId != INVALID_POINTER) {   
-                      final float x = MotionEventCompat.getX(ev, activePointerIndex);   
-                      final int totalDelta = (int) (x - mInitialMotionX);   
-                      int nextPage = determineTargetPage(pageOffset, initialVelocity, totalDelta);   
-                      setCurrentItemInternal(nextPage, true, true, initialVelocity);   
-                  } else {       
-                      setCurrentItemInternal(mCurItem, true, true, initialVelocity);   
-                  }   
-                  mActivePointerId = INVALID_POINTER;   
-                  endDrag();   
-              } else if (mQuickReturn && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) {   
-                  // close the menu   
-                  setCurrentItem(1);   
-                  endDrag();   
-              }   
-              break;   
-          case MotionEvent.ACTION_CANCEL:   
-              if (mIsBeingDragged) {   
-                  setCurrentItemInternal(mCurItem, true, true);   
-                  mActivePointerId = INVALID_POINTER;   
-                  endDrag();   
-              }   
-              break;   
-          case MotionEventCompat.ACTION_POINTER_DOWN: {   
-              final int indexx = MotionEventCompat.getActionIndex(ev);   
-              mLastMotionX = MotionEventCompat.getX(ev, indexx);   
-              mActivePointerId = MotionEventCompat.getPointerId(ev, indexx);   
-              break;   
-          }   
-          case MotionEventCompat.ACTION_POINTER_UP:   
-              onSecondaryPointerUp(ev);   
-              int pointerIndex = getPointerIndex(ev, mActivePointerId);   
-              if (mActivePointerId == INVALID_POINTER)   
-                  break;   
-              mLastMotionX = MotionEventCompat.getX(ev, pointerIndex);   
-              break;   
-          }   
-          return true;   
-      }   
-         
-      private void determineDrag(MotionEvent ev) {   
-          final int activePointerId = mActivePointerId;   
-          final int pointerIndex = getPointerIndex(ev, activePointerId);   
-          if (activePointerId == INVALID_POINTER || pointerIndex == INVALID_POINTER)   
-              return;   
-          final float x = MotionEventCompat.getX(ev, pointerIndex);   
-          final float dx = x - mLastMotionX;   
-          final float xDiff = Math.abs(dx);   
-          final float y = MotionEventCompat.getY(ev, pointerIndex);   
-          final float dy = y - mLastMotionY;   
-          final float yDiff = Math.abs(dy);   
-          if (xDiff > (isMenuOpen()?mTouchSlop/2:mTouchSlop) && xDiff > yDiff && thisSlideAllowed(dx)) {           
-              startDrag();   
-              mLastMotionX = x;   
-              mLastMotionY = y;   
-              setScrollingCacheEnabled(true);   
-              // TODO add back in touch slop check   
-          } else if (xDiff > mTouchSlop) {   
-              mIsUnableToDrag = true;   
-          }   
-      }   
-     
-      @Override   
-      public void scrollTo(int x, int y) {   
-          super.scrollTo(x, y);   
-          mScrollX = x;   
-          mViewBehind.scrollBehindTo(mContent, x, y);    
-         ((SlidingMenu)getParent()).manageLayers(getPercentOpen());   
-             
-          if (mTransformer != null) {   
-              invalidate();   
-          }   
-      }   
-     
-      private int determineTargetPage(float pageOffset, int velocity, int deltaX) {   
-          int targetPage = mCurItem;   
-          if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) {   
-              if (velocity > 0 && deltaX > 0) {   
-                  targetPage -= 1;   
-              } else if (velocity < 0 && deltaX < 0){   
-                  targetPage += 1;   
-              }   
-          } else {   
-              targetPage = (int) Math.round(mCurItem + pageOffset);   
-          }   
-          return targetPage;   
-      }   
-     
-      protected float getPercentOpen() {   
-          return Math.abs(mScrollX-mContent.getLeft()) / getBehindWidth();   
-      }   
-     
-      @Override   
-      protected void dispatchDraw(Canvas canvas) {   
-          // 这句要注释掉,否则会出现2个右侧的视图,一个有转场动画,一个没有转场动画   
-                  // super.dispatchDraw(canvas);   
-          // Draw the margin drawable if needed.   
-          mViewBehind.drawShadow(mContent, canvas);   
-          mViewBehind.drawFade(mContent, canvas, getPercentOpen());   
-          mViewBehind.drawSelector(mContent, canvas, getPercentOpen());   
-          // 设置右侧视图的转场效果,主要是修改Canvas。   
-          if (mTransformer != null) {   
-              canvas.save();   
-              mTransformer.transformCanvas(canvas, getPercentOpen());   
-              super.dispatchDraw(canvas);   
-              canvas.restore();   
-          } else {   
-              super.dispatchDraw(canvas);   
-          }   
-      }   
-     
-      // variables for drawing   
-      private float mScrollX = 0.0f;   
-     
-      private void onSecondaryPointerUp(MotionEvent ev) {   
-          if (DEBUG) Log.v(TAG, "onSecondaryPointerUp called");   
-          final int pointerIndex = MotionEventCompat.getActionIndex(ev);   
-          final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);   
-          if (pointerId == mActivePointerId) {   
-              // This was our active pointer going up. Choose a new   
-              // active pointer and adjust accordingly.   
-              final int newPointerIndex = pointerIndex == 0 ? 1 : 0;   
-              mLastMotionX = MotionEventCompat.getX(ev, newPointerIndex);   
-              mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);   
-              if (mVelocityTracker != null) {   
-                  mVelocityTracker.clear();   
-              }   
-          }   
-      }   
-     
-      private void startDrag() {   
-          mIsBeingDragged = true;   
-          mQuickReturn = false;   
-      }   
-     
-      private void endDrag() {   
-          mQuickReturn = false;   
-          mIsBeingDragged = false;   
-          mIsUnableToDrag = false;   
-          mActivePointerId = INVALID_POINTER;   
-     
-          if (mVelocityTracker != null) {   
-              mVelocityTracker.recycle();   
-              mVelocityTracker = null;   
-          }   
-      }   
-     
-      private void setScrollingCacheEnabled(boolean enabled) {   
-          if (mScrollingCacheEnabled != enabled) {   
-              mScrollingCacheEnabled = enabled;   
-              if (USE_CACHE) {   
-                  final int size = getChildCount();   
-                  for (int i = 0; i < size; ++i) {   
-                      final View child = getChildAt(i);   
-                      if (child.getVisibility() != GONE) {   
-                          child.setDrawingCacheEnabled(enabled);   
-                      }   
-                  }   
-              }   
-          }   
-      }   
-     
-      /**  
-       * Tests scrollability within child views of v given a delta of dx.  
-       *  
-       * @param v View to test for horizontal scrollability  
-       * @param checkV Whether the view v passed should itself be checked for scrollability (true),  
-       *               or just its children (false).  
-       * @param dx Delta scrolled in pixels  
-       * @param x X coordinate of the active touch point  
-       * @param y Y coordinate of the active touch point  
-       * @return true if child views of v can be scrolled by delta of dx.  
-       */   
-      protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {   
-          if (v instanceof ViewGroup) {   
-              final ViewGroup group = (ViewGroup) v;   
-              final int scrollX = v.getScrollX();   
-              final int scrollY = v.getScrollY();   
-              final int count = group.getChildCount();   
-              // Count backwards - let topmost views consume scroll distance first.   
-              for (int i = count - 1; i >= 0; i--) {   
-                  final View child = group.getChildAt(i);   
-                  if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() &&   
-                          y + scrollY >= child.getTop() && y + scrollY < child.getBottom() &&   
-                          canScroll(child, true, dx, x + scrollX - child.getLeft(),   
-                                  y + scrollY - child.getTop())) {   
-                      return true;   
-                  }   
-              }   
-          }   
-     
-          return checkV && ViewCompat.canScrollHorizontally(v, -dx);   
-      }   
-     
-     
-      @Override   
-      public boolean dispatchKeyEvent(KeyEvent event) {   
-          // Let the focused view and/or our descendants get the key first   
-          return super.dispatchKeyEvent(event) || executeKeyEvent(event);   
-      }   
-     
-      /**  
-       * You can call this function yourself to have the scroll view perform  
-       * scrolling from a key event, just as if the event had been dispatched to  
-       * it by the view hierarchy.  
-       *  
-       * @param event The key event to execute.  
-       * @return Return true if the event was handled, else false.  
-       */   
-      public boolean executeKeyEvent(KeyEvent event) {   
-          boolean handled = false;   
-          if (event.getAction() == KeyEvent.ACTION_DOWN) {   
-              switch (event.getKeyCode()) {   
-              case KeyEvent.KEYCODE_DPAD_LEFT:   
-                  handled = arrowScroll(FOCUS_LEFT);   
-                  break;   
-              case KeyEvent.KEYCODE_DPAD_RIGHT:   
-                  handled = arrowScroll(FOCUS_RIGHT);   
-                  break;   
-              case KeyEvent.KEYCODE_TAB:   
-                  if (Build.VERSION.SDK_INT >= 11) {   
-                      // The focus finder had a bug handling FOCUS_FORWARD and FOCUS_BACKWARD   
-                      // before Android 3.0. Ignore the tab key on those devices.   
-                      if (KeyEventCompat.hasNoModifiers(event)) {   
-                          handled = arrowScroll(FOCUS_FORWARD);   
-                      } else if (KeyEventCompat.hasModifiers(event, KeyEvent.META_SHIFT_ON)) {   
-                          handled = arrowScroll(FOCUS_BACKWARD);   
-                      }   
-                  }   
-                  break;   
-              }   
-          }   
-          return handled;   
-      }   
-     
-      public boolean arrowScroll(int direction) {   
-          View currentFocused = findFocus();   
-          if (currentFocused == this) currentFocused = null;   
-     
-          boolean handled = false;   
-     
-          View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused,   
-                  direction);   
-          if (nextFocused != null && nextFocused != currentFocused) {   
-              if (direction == View.FOCUS_LEFT) {   
-                  handled = nextFocused.requestFocus();   
-              } else if (direction == View.FOCUS_RIGHT) {   
-                  // If there is nothing to the right, or this is causing us to   
-                  // jump to the left, then what we really want to do is page right.   
-                  if (currentFocused != null && nextFocused.getLeft() <= currentFocused.getLeft()) {   
-                      handled = pageRight();   
-                  } else {   
-                      handled = nextFocused.requestFocus();   
-                  }   
-              }   
-          } else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) {   
-              // Trying to move left and nothing there; try to page.   
-              handled = pageLeft();   
-          } else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) {   
-              // Trying to move right and nothing there; try to page.   
-              handled = pageRight();   
-          }   
-          if (handled) {   
-              playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));   
-          }   
-          return handled;   
-      }   
-     
-      boolean pageLeft() {   
-          if (mCurItem > 0) {   
-              setCurrentItem(mCurItem-1, true);   
-              return true;   
-          }   
-          return false;   
-      }   
-     
-      boolean pageRight() {   
-          if (mCurItem < 1) {   
-              setCurrentItem(mCurItem+1, true);   
-              return true;   
-          }   
-          return false;   
-      }   
-         
-      public void setCanvasTransformer(CanvasTransformer t) {   
-          mTransformer = t;   
-      }   
-         
-  }   
  
如果想要使用这个侧滑菜单的动画效果,直接替换这两个类即可。同时,并不会影响SlidingMenu的固有功能。 
 下面看看如何配置SlidingMenu实例。 
 
 
  
  
  -  SlidingMenu sm = getSlidingMenu();   
-  sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);   
-  sm.setFadeEnabled(false);   
-  sm.setBehindScrollScale(0.25f);   
-  sm.setFadeDegree(0.25f);   
-     
-  // 配置背景图片   
-  sm.setBackgroundImage(R.drawable.img_frame_background);   
-  // 设置专场动画效果   
-  sm.setBehindCanvasTransformer(new SlidingMenu.CanvasTransformer() {   
-      @Override   
-      public void transformCanvas(Canvas canvas, float percentOpen) {   
-          float scale = (float) (percentOpen * 0.25 + 0.75);   
-          canvas.scale(scale, scale, -canvas.getWidth() / 2,   
-                  canvas.getHeight() / 2);   
-      }   
-  });   
-     
-  sm.setAboveCanvasTransformer(new SlidingMenu.CanvasTransformer() {   
-      @Override   
-      public void transformCanvas(Canvas canvas, float percentOpen) {   
-          float scale = (float) (1 - percentOpen * 0.25);   
-          canvas.scale(scale, scale, 0, canvas.getHeight() / 2);   
-      }   
-  });   
  
 大功告成! 
 
 最后,附上Demo的下载地址。 
 
 GitHub https://github.com/sunguowei/Android-ResideMenu 
 
 CSDN资源   http://download.csdn.net/detail/manoel/7857771 
 
 百度网盘    http://pan.baidu.com/s/1jGrASui 
 
 
 
 
 关于这个框架后期的优化,请关注我的github。 
 
 https://github.com/sunguowei 
 
  
 
 Okay,要说的就这么多,希望能给大家带来一些帮助。 
【案例分享】仿QQ5.0侧滑菜单ResideMenu
标签:des   android   style   blog   http   io   color   os   ar   
原文地址:http://my.oschina.net/u/1402271/blog/337691