欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-16 10:35:04
androidsidemenu能够让你轻而易举地创建侧滑菜单。需要注意的是,该项目自身并不提供任何创建菜单的工具,因此,开发者可以*创建内部菜单。 核心类如下:...

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

Android开源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

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

上一篇:

下一篇: