Android开发

Android开源AndroidSideMenu实现抽屉和侧滑菜单

本文主要是介绍Android开源AndroidSideMenu实现抽屉和侧滑菜单,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

AndroidSideMenu能够让你轻而易举地创建侧滑菜单。需要注意的是,该项目自身并不提供任何创建菜单的工具,因此,开发者可以自由创建内部菜单。

核心类如下:

/* 
 * Copyright dmitry.zaicew@gmail.com Dmitry Zaitsev 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */ 
 
package com.agimind.widget; 
 
import java.util.LinkedList; 
import java.util.Queue; 
 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PorterDuff.Mode; 
import android.graphics.Rect; 
import android.graphics.Region.Op; 
import android.os.Build; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.animation.Animation; 
import android.view.animation.DecelerateInterpolator; 
import android.view.animation.Transformation; 
import android.widget.FrameLayout; 
 
public class SlideHolder extends FrameLayout { 
 
  public final static int DIRECTION_LEFT = 1; 
  public final static int DIRECTION_RIGHT = -1; 
   
  protected final static int MODE_READY = 0; 
  protected final static int MODE_SLIDE = 1; 
  protected final static int MODE_FINISHED = 2; 
   
  private Bitmap mCachedBitmap; 
  private Canvas mCachedCanvas; 
  private Paint mCachedPaint; 
  private View mMenuView; 
   
  private int mMode = MODE_READY; 
  private int mDirection = DIRECTION_LEFT; 
   
  private int mOffset = 0; 
  private int mStartOffset; 
  private int mEndOffset; 
   
  private boolean mEnabled = true; 
  private boolean mInterceptTouch = true; 
  private boolean mAlwaysOpened = false; 
  private boolean mDispatchWhenOpened = false; 
   
  private Queue<Runnable> mWhenReady = new LinkedList<Runnable>(); 
   
  private OnSlideListener mListener; 
   
  public SlideHolder(Context context) { 
    super(context); 
     
    initView(); 
  } 
   
  public SlideHolder(Context context, AttributeSet attrs) { 
    super(context, attrs); 
     
    initView(); 
  } 
   
  public SlideHolder(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
     
    initView(); 
  } 
   
  private void initView() { 
    mCachedPaint = new Paint( 
          Paint.ANTI_ALIAS_FLAG 
          | Paint.FILTER_BITMAP_FLAG 
          | Paint.DITHER_FLAG 
        ); 
  } 
   
  @Override 
  public void setEnabled(boolean enabled) { 
    mEnabled = enabled; 
  } 
   
  @Override 
  public boolean isEnabled() { 
    return mEnabled; 
  } 
   
  /** 
   * 
   * @param direction - direction in which SlideHolder opens. Can be: DIRECTION_LEFT, DIRECTION_RIGHT 
   */ 
  public void setDirection(int direction) { 
    closeImmediately(); 
     
    mDirection = direction; 
  } 
   
  /** 
   * 
   * @param allow - if false, SlideHolder won't react to swiping gestures (but still will be able to work by manually invoking mathods) 
   */ 
  public void setAllowInterceptTouch(boolean allow) { 
    mInterceptTouch = allow; 
  } 
   
  public boolean isAllowedInterceptTouch() { 
    return mInterceptTouch; 
  } 
   
  /** 
   * 
   * @param dispatch - if true, in open state SlideHolder will dispatch touch events to main layout (in other words - it will be clickable) 
   */ 
  public void setDispatchTouchWhenOpened(boolean dispatch) { 
    mDispatchWhenOpened = dispatch; 
  } 
   
  public boolean isDispatchTouchWhenOpened() { 
    return mDispatchWhenOpened; 
  } 
   
  /** 
   * 
   * @param opened - if true, SlideHolder will always be in opened state (which means that swiping won't work) 
   */ 
  public void setAlwaysOpened(boolean opened) { 
    mAlwaysOpened = opened; 
     
    requestLayout(); 
  } 
   
  public int getMenuOffset() { 
    return mOffset; 
  } 
   
  public void setOnSlideListener(OnSlideListener lis) { 
    mListener = lis; 
  } 
   
  public boolean isOpened() { 
    return mAlwaysOpened || mMode == MODE_FINISHED; 
  } 
   
  public void toggle(boolean immediately) { 
    if(immediately) { 
      toggleImmediately(); 
    } else { 
      toggle(); 
    } 
  } 
   
  public void toggle() { 
    if(isOpened()) { 
      close(); 
    } else { 
      open(); 
    } 
  } 
   
  public void toggleImmediately() { 
    if(isOpened()) { 
      closeImmediately(); 
    } else { 
      openImmediately(); 
    } 
  } 
   
  public boolean open() { 
    if(isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) { 
      return false; 
    } 
     
    if(!isReadyForSlide()) { 
      mWhenReady.add(new Runnable() { 
         
        @Override 
        public void run() { 
          open(); 
        } 
      }); 
       
      return true; 
    } 
     
    initSlideMode(); 
     
    Animation anim = new SlideAnimation(mOffset, mEndOffset); 
    anim.setAnimationListener(mOpenListener); 
    startAnimation(anim); 
     
    invalidate(); 
     
    return true; 
  } 
   
  public boolean openImmediately() { 
    if(isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) { 
      return false; 
    } 
     
    if(!isReadyForSlide()) { 
      mWhenReady.add(new Runnable() { 
         
        @Override 
        public void run() { 
          openImmediately(); 
        } 
      }); 
       
      return true; 
    } 
     
    mMenuView.setVisibility(View.VISIBLE); 
    mMode = MODE_FINISHED; 
    requestLayout(); 
     
    if(mListener != null) { 
      mListener.onSlideCompleted(true); 
    } 
     
    return true; 
  } 
   
  public boolean close() { 
    if(!isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) { 
      return false; 
    } 
     
    if(!isReadyForSlide()) { 
      mWhenReady.add(new Runnable() { 
         
        @Override 
        public void run() { 
          close(); 
        } 
      }); 
       
      return true; 
    } 
     
    initSlideMode(); 
     
    Animation anim = new SlideAnimation(mOffset, mEndOffset); 
    anim.setAnimationListener(mCloseListener); 
    startAnimation(anim); 
     
    invalidate(); 
     
    return true; 
  } 
   
  public boolean closeImmediately() { 
    if(!isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) { 
      return false; 
    } 
     
    if(!isReadyForSlide()) { 
      mWhenReady.add(new Runnable() { 
         
        @Override 
        public void run() { 
          closeImmediately(); 
        } 
      }); 
       
      return true; 
    } 
     
    mMenuView.setVisibility(View.GONE); 
    mMode = MODE_READY; 
    requestLayout(); 
     
    if(mListener != null) { 
      mListener.onSlideCompleted(false); 
    } 
     
    return true; 
  } 
   
  @Override 
  protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    final int parentLeft = 0; 
    final int parentTop = 0; 
    final int parentRight = r - l; 
    final int parentBottom = b - t; 
     
    View menu = getChildAt(0); 
    int menuWidth = menu.getMeasuredWidth(); 
     
    if(mDirection == DIRECTION_LEFT) { 
      menu.layout(parentLeft, parentTop, parentLeft+menuWidth, parentBottom); 
    } else { 
      menu.layout(parentRight-menuWidth, parentTop, parentRight, parentBottom); 
    } 
     
    if(mAlwaysOpened) { 
      if(mDirection == DIRECTION_LEFT) { 
        mOffset = menuWidth; 
      } else { 
        mOffset = 0; 
      } 
    } else if(mMode == MODE_FINISHED) { 
      mOffset = mDirection*menuWidth; 
    } else if(mMode == MODE_READY) { 
      mOffset = 0; 
    } 
     
    View main = getChildAt(1); 
    main.layout( 
          parentLeft + mOffset, 
          parentTop, 
          parentLeft + mOffset + main.getMeasuredWidth(), 
          parentBottom 
        ); 
     
    invalidate(); 
     
    Runnable rn; 
    while((rn = mWhenReady.poll()) != null) { 
      rn.run(); 
    } 
  } 
   
  private boolean isReadyForSlide() { 
    return (getWidth() > 0 && getHeight() > 0); 
  } 
   
  @Override 
  protected void onMeasure(int wSp, int hSp) { 
    mMenuView = getChildAt(0); 
     
    if(mAlwaysOpened) { 
      View main = getChildAt(1); 
       
      if(mMenuView != null && main != null) { 
        measureChild(mMenuView, wSp, hSp); 
        LayoutParams lp = (LayoutParams) main.getLayoutParams(); 
         
        if(mDirection == DIRECTION_LEFT) { 
          lp.leftMargin = mMenuView.getMeasuredWidth(); 
        } else { 
          lp.rightMargin = mMenuView.getMeasuredWidth(); 
        } 
      } 
    } 
     
    super.onMeasure(wSp, hSp); 
  } 
 
  private byte mFrame = 0; 
   
  @Override 
  protected void dispatchDraw(Canvas canvas) { 
    try { 
      if(mMode == MODE_SLIDE) { 
        View main = getChildAt(1); 
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
          /* 
           * On new versions we redrawing main layout only 
           * if it's marked as dirty 
           */ 
          if(main.isDirty()) { 
            mCachedCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
            main.draw(mCachedCanvas); 
        } 
        } else { 
          /* 
           * On older versions we just redrawing our cache 
           * every 5th frame 
           */ 
          if(++mFrame % 5 == 0) { 
            mCachedCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
            main.draw(mCachedCanvas); 
          } 
        } 
 
        /* 
         * Draw only visible part of menu 
         */ 
         
        View menu = getChildAt(0); 
        final int scrollX = menu.getScrollX(); 
        final int scrollY = menu.getScrollY(); 
         
        canvas.save(); 
         
        if(mDirection == DIRECTION_LEFT) { 
          canvas.clipRect(0, 0, mOffset, menu.getHeight(), Op.REPLACE); 
        } else { 
          int menuWidth = menu.getWidth(); 
          int menuLeft = menu.getLeft(); 
           
          canvas.clipRect(menuLeft+menuWidth+mOffset, 0, menuLeft+menuWidth, menu.getHeight()); 
        } 
         
        canvas.translate(menu.getLeft(), menu.getTop()); 
        canvas.translate(-scrollX, -scrollY); 
         
        menu.draw(canvas); 
         
        canvas.restore(); 
         
        canvas.drawBitmap(mCachedBitmap, mOffset, 0, mCachedPaint); 
      } else { 
        if(!mAlwaysOpened && mMode == MODE_READY) { 
          mMenuView.setVisibility(View.GONE); 
        } 
         
        super.dispatchDraw(canvas); 
      } 
    } catch(IndexOutOfBoundsException e) { 
      /* 
       * Possibility of crashes on some devices (especially on Samsung). 
       * Usually, when ListView is empty. 
       */ 
    } 
  } 
   
  private int mHistoricalX = 0; 
  private boolean mCloseOnRelease = false; 
   
  @Override 
  public boolean dispatchTouchEvent(MotionEvent ev) { 
    if(((!mEnabled || !mInterceptTouch) && mMode == MODE_READY) || mAlwaysOpened) { 
      return super.dispatchTouchEvent(ev); 
    } 
     
    if(mMode != MODE_FINISHED) { 
      onTouchEvent(ev); 
       
      if(mMode != MODE_SLIDE) { 
        super.dispatchTouchEvent(ev); 
      } else { 
        MotionEvent cancelEvent = MotionEvent.obtain(ev); 
        cancelEvent.setAction(MotionEvent.ACTION_CANCEL); 
        super.dispatchTouchEvent(cancelEvent); 
        cancelEvent.recycle(); 
      } 
       
      return true; 
    } else { 
      final int action = ev.getAction(); 
       
      Rect rect = new Rect(); 
      View menu = getChildAt(0); 
      menu.getHitRect(rect); 
       
      if(!rect.contains((int) ev.getX(), (int) ev.getY())) { 
        if (action == MotionEvent.ACTION_UP && mCloseOnRelease && !mDispatchWhenOpened) { 
          close(); 
          mCloseOnRelease = false; 
        } else { 
          if(action == MotionEvent.ACTION_DOWN && !mDispatchWhenOpened) { 
            mCloseOnRelease = true; 
          } 
           
          onTouchEvent(ev); 
        } 
         
        if(mDispatchWhenOpened) { 
          super.dispatchTouchEvent(ev); 
        } 
         
        return true; 
      } else { 
        onTouchEvent(ev); 
         
        ev.offsetLocation(-menu.getLeft(), -menu.getTop()); 
        menu.dispatchTouchEvent(ev); 
         
        return true; 
      } 
    } 
  } 
   
  private boolean handleTouchEvent(MotionEvent ev) { 
    if(!mEnabled) { 
      return false; 
    } 
     
    float x = ev.getX(); 
     
    if(ev.getAction() == MotionEvent.ACTION_DOWN) { 
      mHistoricalX = (int) x; 
       
      return true; 
    } 
     
    if(ev.getAction() == MotionEvent.ACTION_MOVE) { 
 
      float diff = x - mHistoricalX; 
 
      if((mDirection*diff > 50 && mMode == MODE_READY) || (mDirection*diff < -50 && mMode == MODE_FINISHED)) { 
        mHistoricalX = (int) x; 
         
        initSlideMode(); 
      } else if(mMode == MODE_SLIDE) { 
        mOffset += diff; 
         
        mHistoricalX = (int) x; 
         
        if(!isSlideAllowed()) { 
          finishSlide(); 
        } 
      } else { 
        return false; 
      } 
    } 
     
    if(ev.getAction() == MotionEvent.ACTION_UP) { 
      if(mMode == MODE_SLIDE) { 
        finishSlide(); 
      } 
       
      mCloseOnRelease = false; 
       
      return false; 
    } 
     
    return mMode == MODE_SLIDE; 
  } 
   
  @Override 
  public boolean onTouchEvent(MotionEvent ev) { 
    boolean handled = handleTouchEvent(ev); 
     
    invalidate(); 
     
    return handled; 
  } 
   
  private void initSlideMode() { 
    mCloseOnRelease = false; 
     
    View v = getChildAt(1); 
     
    if(mMode == MODE_READY) { 
      mStartOffset = 0; 
      mEndOffset = mDirection*getChildAt(0).getWidth(); 
    } else { 
      mStartOffset = mDirection*getChildAt(0).getWidth(); 
      mEndOffset = 0; 
    } 
     
    mOffset = mStartOffset; 
     
    if(mCachedBitmap == null || mCachedBitmap.isRecycled() || mCachedBitmap.getWidth() != v.getWidth()) { 
      mCachedBitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888); 
      mCachedCanvas = new Canvas(mCachedBitmap); 
    } else { 
      mCachedCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
    } 
     
    v.setVisibility(View.VISIBLE); 
     
    mCachedCanvas.translate(-v.getScrollX(), -v.getScrollY()); 
    v.draw(mCachedCanvas); 
     
    mMode = MODE_SLIDE; 
     
    mMenuView.setVisibility(View.VISIBLE); 
  } 
   
  private boolean isSlideAllowed() { 
    return (mDirection*mEndOffset > 0 && mDirection*mOffset < mDirection*mEndOffset && mDirection*mOffset >= mDirection*mStartOffset) 
        || (mEndOffset == 0 && mDirection*mOffset > mDirection*mEndOffset && mDirection*mOffset <= mDirection*mStartOffset); 
  } 
   
  private void completeOpening() { 
    mOffset = mDirection*mMenuView.getWidth(); 
    requestLayout(); 
     
    post(new Runnable() { 
       
      @Override 
      public void run() { 
        mMode = MODE_FINISHED; 
        mMenuView.setVisibility(View.VISIBLE); 
      } 
    }); 
     
    if(mListener != null) { 
      mListener.onSlideCompleted(true); 
    } 
  } 
   
  private Animation.AnimationListener mOpenListener = new Animation.AnimationListener() { 
     
    @Override 
    public void onAnimationStart(Animation animation) {} 
     
    @Override 
    public void onAnimationRepeat(Animation animation) {} 
     
    @Override 
    public void onAnimationEnd(Animation animation) { 
      completeOpening(); 
    } 
  }; 
   
  private void completeClosing() { 
    mOffset = 0; 
    requestLayout(); 
     
    post(new Runnable() { 
       
      @Override 
      public void run() { 
        mMode = MODE_READY; 
        mMenuView.setVisibility(View.GONE); 
      } 
    }); 
     
    if(mListener != null) { 
      mListener.onSlideCompleted(false); 
    } 
  } 
   
  private Animation.AnimationListener mCloseListener = new Animation.AnimationListener() { 
     
    @Override 
    public void onAnimationStart(Animation animation) {} 
     
    @Override 
    public void onAnimationRepeat(Animation animation) {} 
     
    @Override 
    public void onAnimationEnd(Animation animation) { 
      completeClosing(); 
    } 
  }; 
   
  private void finishSlide() { 
    if(mDirection*mEndOffset > 0) { 
      if(mDirection*mOffset > mDirection*mEndOffset/2) { 
        if(mDirection*mOffset > mDirection*mEndOffset) mOffset = mEndOffset; 
         
        Animation anim = new SlideAnimation(mOffset, mEndOffset); 
        anim.setAnimationListener(mOpenListener); 
        startAnimation(anim); 
      } else { 
        if(mDirection*mOffset < mDirection*mStartOffset) mOffset = mStartOffset; 
         
        Animation anim = new SlideAnimation(mOffset, mStartOffset); 
        anim.setAnimationListener(mCloseListener); 
        startAnimation(anim); 
      } 
    } else { 
      if(mDirection*mOffset < mDirection*mStartOffset/2) { 
        if(mDirection*mOffset < mDirection*mEndOffset) mOffset = mEndOffset; 
         
        Animation anim = new SlideAnimation(mOffset, mEndOffset); 
        anim.setAnimationListener(mCloseListener); 
        startAnimation(anim); 
      } else { 
        if(mDirection*mOffset > mDirection*mStartOffset) mOffset = mStartOffset; 
         
        Animation anim = new SlideAnimation(mOffset, mStartOffset); 
        anim.setAnimationListener(mOpenListener); 
        startAnimation(anim); 
      } 
    } 
  } 
   
  private class SlideAnimation extends Animation { 
     
    private static final float SPEED = 0.6f; 
     
    private float mStart; 
    private float mEnd; 
     
    public SlideAnimation(float fromX, float toX) { 
      mStart = fromX; 
      mEnd = toX; 
       
      setInterpolator(new DecelerateInterpolator()); 
 
      float duration = Math.abs(mEnd - mStart) / SPEED; 
      setDuration((long) duration); 
    } 
     
    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
      super.applyTransformation(interpolatedTime, t); 
       
      float offset = (mEnd - mStart) * interpolatedTime + mStart; 
      mOffset = (int) offset; 
       
      postInvalidate(); 
    } 
     
  } 
   
  public static interface OnSlideListener { 
    public void onSlideCompleted(boolean opened); 
  } 
 
} 

使用:

package com.agimind.sidemenuexample; 
 
import com.agimind.widget.SlideHolder; 
 
import android.os.Bundle; 
import android.view.MenuItem; 
import android.view.View; 
import android.app.ActionBar; 
import android.app.Activity; 
 
public class MainActivity extends Activity { 
 
  private SlideHolder mSlideHolder; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
 
    mSlideHolder = (SlideHolder) findViewById(R.id.slideHolder); 
    // mSlideHolder.setAllowInterceptTouch(false); 
    // mSlideHolder.setAlwaysOpened(true); 
    /* 
     * toggleView can actually be any view you want. Here, for simplicity, 
     * we're using TextView, but you can easily replace it with button. 
     * 
     * Note, when menu opens our textView will become invisible, so it quite 
     * pointless to assign toggle-event to it. In real app consider using UP 
     * button instead. In our case toggle() can be replaced with open(). 
     */ 
 
    ActionBar actionBar = getActionBar(); 
    actionBar.setDisplayShowHomeEnabled(true); 
    actionBar.setHomeButtonEnabled(true); 
     
    View toggleView = findViewById(R.id.textView); 
    toggleView.setOnClickListener(new View.OnClickListener() { 
 
      @Override 
      public void onClick(View v) { 
        mSlideHolder.toggle(); 
      } 
    }); 
  } 
 
  @Override 
  public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
    case android.R.id.home: 
      mSlideHolder.toggle(); 
      break; 
 
    default: 
      break; 
    } 
    return super.onOptionsItemSelected(item); 
  } 
} 

布局如下:

<com.agimind.widget.SlideHolder xmlns:android="http://schemas.android.com/apk/res/android" 
  xmlns:tools="http://schemas.android.com/tools" 
  android:id="@+id/slideHolder" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  tools:context=".MainActivity" > 
 
  <ScrollView 
    android:layout_width="200dp" 
    android:layout_height="fill_parent" 
    android:background="@android:color/black" > 
 
    <LinearLayout 
      android:layout_width="200dp" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" > 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
 
      <Button 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/menu_settings" /> 
    </LinearLayout> 
  </ScrollView> 
 
  <RelativeLayout 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 
 
    <TextView 
      android:id="@+id/textView" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:layout_centerVertical="true" 
      android:text="@string/swipe" 
      android:textSize="25sp" /> 
 
  </RelativeLayout> 
 
</com.agimind.widget.SlideHolder> 

下载:AndroidSideMenu

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持找一找教程网。

这篇关于Android开源AndroidSideMenu实现抽屉和侧滑菜单的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!