当前位置: 移动技术网 > IT编程>移动开发>Android > 代码分析Android实现侧滑菜单

代码分析Android实现侧滑菜单

2019年07月24日  | 移动技术网IT编程  | 我要评论

婚礼布置,濑亚美莉喷奶 qvod,吴玥菲

android 侧滑菜单的实现,参考网上的代码,实现侧滑菜单。最重要的是这个动画类ugcanimations,如何使用动画类来侧滑的封装flipperlayout。

1、实现效果

2、动画类ugcanimations

package com.mmsx.base; 
import android.content.context; 
import android.view.view; 
import android.view.viewgroup.marginlayoutparams; 
import android.view.animation.alphaanimation; 
import android.view.animation.animation; 
import android.view.animation.animationset; 
import android.view.animation.anticipateinterpolator; 
import android.view.animation.overshootinterpolator; 
import android.view.animation.rotateanimation; 
import android.view.animation.scaleanimation; 
import android.view.animation.translateanimation; 
import android.widget.imageview; 
import android.widget.relativelayout; 
 
/** 
 * path动画类 
 * 
 */ 
public class ugcanimations { 
  private static int xoffset = 15; 
  private static int yoffset = -13; 
 
  public static void initoffset(context context) { 
    xoffset = (int) (15 * context.getresources().getdisplaymetrics().density); 
    yoffset = -(int) (13 * context.getresources().getdisplaymetrics().density); 
  } 
 
  public static animation getrotateanimation(float fromdegrees, 
      float todegrees, long durationmillis) { 
    rotateanimation rotate = new rotateanimation(fromdegrees, todegrees, 
        animation.relative_to_self, 0.5f, animation.relative_to_self, 
        0.5f); 
    rotate.setduration(durationmillis); 
    rotate.setfillafter(true); 
    return rotate; 
  } 
 
  public static animation getalphaanimation(float fromalpha, float toalpha, 
      long durationmillis) { 
    alphaanimation alpha = new alphaanimation(fromalpha, toalpha); 
    alpha.setduration(durationmillis); 
    alpha.setfillafter(true); 
    return alpha; 
  } 
 
  public static animation getscaleanimation(long durationmillis) { 
    scaleanimation scale = new scaleanimation(1.0f, 1.5f, 1.0f, 1.5f, 
        animation.relative_to_self, 0.5f, animation.relative_to_self, 
        0.5f); 
    scale.setduration(durationmillis); 
    return scale; 
  } 
 
  public static animation gettranslateanimation(float fromxdelta, 
      float toxdelta, float fromydelta, float toydelta, 
      long durationmillis) { 
    translateanimation translate = new translateanimation(fromxdelta, 
        toxdelta, fromydelta, toydelta); 
    translate.setduration(durationmillis); 
    translate.setfillafter(true); 
    return translate; 
  } 
 
  public static void startopenanimation(relativelayout relativelayout, 
      imageview background, imageview menu, long durationmillis) { 
    background.setvisibility(view.visible); 
    relativelayout.setvisibility(view.visible); 
    background.startanimation(getalphaanimation(0f, 1f, durationmillis)); 
    menu.startanimation(getrotateanimation(0, 90, durationmillis)); 
    for (int i = 0; i < relativelayout.getchildcount(); i++) { 
      imageview imageview = (imageview) relativelayout.getchildat(i); 
      imageview.setvisibility(view.visible); 
      marginlayoutparams params = (marginlayoutparams) imageview 
          .getlayoutparams(); 
      animationset set = new animationset(true); 
      set.addanimation(getrotateanimation(-270, 0, durationmillis)); 
      set.addanimation(getalphaanimation(0.5f, 1.0f, durationmillis)); 
      set.addanimation(gettranslateanimation( 
          -params.leftmargin + xoffset, 0f, params.bottommargin 
              + yoffset, 0f, durationmillis)); 
      set.setfillafter(true); 
      set.setduration(durationmillis); 
      set.setstartoffset((i * 100) 
          / (-1 + relativelayout.getchildcount())); 
      set.setinterpolator(new overshootinterpolator(1f)); 
      imageview.startanimation(set); 
    } 
  } 
  public static void startcloseanimation(final relativelayout relativelayout, 
      final imageview background, imageview menu, long durationmillis) { 
    background.startanimation(getalphaanimation(1f, 0f, durationmillis)); 
    menu.startanimation(getrotateanimation(90, 0, durationmillis)); 
    for (int i = 0; i < relativelayout.getchildcount(); i++) { 
      final imageview imageview = (imageview) relativelayout 
          .getchildat(i); 
      marginlayoutparams params = (marginlayoutparams) imageview 
          .getlayoutparams(); 
      animationset set = new animationset(true); 
      set.addanimation(getrotateanimation(0, -270, durationmillis)); 
      set.addanimation(getalphaanimation(1.0f, 0.5f, durationmillis)); 
      set.addanimation(gettranslateanimation(0f, -params.leftmargin 
          + xoffset, 0f, params.bottommargin + yoffset, 
          durationmillis)); 
      set.setfillafter(true); 
      set.setduration(durationmillis); 
      set.setstartoffset(((relativelayout.getchildcount() - i) * 100) 
          / (-1 + relativelayout.getchildcount())); 
      set.setinterpolator(new anticipateinterpolator(1f)); 
      set.setanimationlistener(new animation.animationlistener() { 
        public void onanimationstart(animation arg0) { 
        } 
        public void onanimationrepeat(animation arg0) { 
        } 
        public void onanimationend(animation arg0) { 
          relativelayout.setvisibility(view.gone); 
          background.setvisibility(view.gone); 
        } 
      }); 
      imageview.startanimation(set); 
    } 
  } 
  public static animation clickanimation(long durationmillis) { 
    animationset set = new animationset(true); 
    set.addanimation(getalphaanimation(1.0f, 0.3f, durationmillis)); 
    set.addanimation(getscaleanimation(durationmillis)); 
    set.setduration(durationmillis); 
    return set; 
  } 
} 

3、封装使用动画类flipperlayout

package com.mmsx.base; 
import android.content.context; 
import android.util.attributeset; 
import android.util.typedvalue; 
import android.view.motionevent; 
import android.view.velocitytracker; 
import android.view.view; 
import android.view.viewconfiguration; 
import android.view.viewgroup; 
import android.widget.scroller; 
 
/** 
 * 自己重写的viewgroup,用与滑动切换界面使用,代码不详解,慢点看的话应该能看懂的... 
 */ 
public class flipperlayout extends viewgroup { 
 
  private scroller mscroller; 
  private velocitytracker mvelocitytracker; 
  private int mwidth; 
 
  public static final int screen_state_close = 0; 
  public static final int screen_state_open = 1; 
  public static final int touch_state_restart = 0; 
  public static final int touch_state_scrolling = 1; 
  public static final int scroll_state_no_allow = 0; 
  public static final int scroll_state_allow = 1; 
  private int mscreenstate = 0; 
  private int mtouchstate = 0; 
  private int mscrollstate = 0; 
  private int mvelocityvalue = 0; 
  private boolean monclick = false; 
  private onugcdismisslistener monugcdismisslistener; 
  private onugcshowlistener monugcshowlistener; 
 
  public flipperlayout(context context) { 
    super(context); 
    mscroller = new scroller(context); 
    mwidth = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 
        54, getresources().getdisplaymetrics()); 
 
  } 
 
  public flipperlayout(context context, attributeset attrs, int defstyle) { 
    super(context, attrs, defstyle); 
  } 
 
  public flipperlayout(context context, attributeset attrs) { 
    super(context, attrs); 
  } 
 
  protected void onlayout(boolean changed, int l, int t, int r, int b) { 
    for (int i = 0; i < getchildcount(); i++) { 
      view child = getchildat(i); 
      int height = child.getmeasuredheight(); 
      int width = child.getmeasuredwidth(); 
      child.layout(0, 0, width, height); 
    } 
  } 
 
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { 
    super.onmeasure(widthmeasurespec, heightmeasurespec); 
    int width = measurespec.getsize(widthmeasurespec); 
    int height = measurespec.getsize(heightmeasurespec); 
    setmeasureddimension(width, height); 
    for (int i = 0; i < getchildcount(); i++) { 
      getchildat(i).measure(widthmeasurespec, heightmeasurespec); 
    } 
  } 
 
  public boolean dispatchtouchevent(motionevent ev) { 
    obtainvelocitytracker(ev); 
    switch (ev.getaction()) { 
    case motionevent.action_down: 
      mtouchstate = mscroller.isfinished() ? touch_state_restart 
          : touch_state_scrolling; 
      if (mtouchstate == touch_state_restart) { 
        int x = (int) ev.getx(); 
        int screenwidth = getwidth(); 
        if (x <= mwidth && mscreenstate == screen_state_close 
            && mtouchstate == touch_state_restart 
            || x >= screenwidth - mwidth 
            && mscreenstate == screen_state_open 
            && mtouchstate == touch_state_restart) { 
          if (mscreenstate == screen_state_open) { 
            monclick = true; 
          } 
          mscrollstate = scroll_state_allow; 
        } else { 
          monclick = false; 
          mscrollstate = scroll_state_no_allow; 
        } 
      } else { 
        return false; 
      } 
      break; 
    case motionevent.action_move: 
      mvelocitytracker.computecurrentvelocity(1000, 
          viewconfiguration.getmaximumflingvelocity()); 
      if (mscrollstate == scroll_state_allow 
          && getwidth() - (int) ev.getx() < mwidth) { 
        return true; 
      } 
      break; 
    case motionevent.action_up: 
      releasevelocitytracker(); 
      if (monclick) { 
        monclick = false; 
        mscreenstate = screen_state_close; 
        mscroller.startscroll(getchildat(1).getscrollx(), 0, 
            -getchildat(1).getscrollx(), 0, 800); 
        invalidate(); 
      } 
      break; 
    } 
    return super.dispatchtouchevent(ev); 
  } 
 
  public boolean onintercepttouchevent(motionevent ev) { 
    obtainvelocitytracker(ev); 
    switch (ev.getaction()) { 
    case motionevent.action_down: 
      mtouchstate = mscroller.isfinished() ? touch_state_restart 
          : touch_state_scrolling; 
      if (mtouchstate == touch_state_scrolling) { 
        return false; 
      } 
      break; 
 
    case motionevent.action_move: 
      monclick = false; 
      mvelocitytracker.computecurrentvelocity(1000, 
          viewconfiguration.getmaximumflingvelocity()); 
      if (mscrollstate == scroll_state_allow 
          && math.abs(mvelocitytracker.getxvelocity()) > 200) { 
        return true; 
      } 
      break; 
 
    case motionevent.action_up: 
      releasevelocitytracker(); 
      if (mscrollstate == scroll_state_allow 
          && mscreenstate == screen_state_open) { 
        return true; 
      } 
      break; 
    } 
    return super.onintercepttouchevent(ev); 
  } 
 
  public boolean ontouchevent(motionevent event) { 
    obtainvelocitytracker(event); 
    switch (event.getaction()) { 
    case motionevent.action_down: 
      mtouchstate = mscroller.isfinished() ? touch_state_restart 
          : touch_state_scrolling; 
      if (mtouchstate == touch_state_scrolling) { 
        return false; 
      } 
      break; 
 
    case motionevent.action_move: 
      mvelocitytracker.computecurrentvelocity(1000, 
          viewconfiguration.getmaximumflingvelocity()); 
      mvelocityvalue = (int) mvelocitytracker.getxvelocity(); 
      getchildat(1).scrollto(-(int) event.getx(), 0); 
      break; 
 
    case motionevent.action_up: 
      if (mscrollstate == scroll_state_allow) { 
        if (mvelocityvalue > 2000) { 
          mscreenstate = screen_state_open; 
          mscroller 
              .startscroll( 
                  getchildat(1).getscrollx(), 
                  0, 
                  -(getwidth() 
                      - math.abs(getchildat(1) 
                          .getscrollx()) - 
 
                  mwidth), 0, 250); 
          invalidate(); 
 
        } else if (mvelocityvalue < -2000) { 
          mscreenstate = screen_state_close; 
          mscroller.startscroll(getchildat(1).getscrollx(), 0, 
              -getchildat(1).getscrollx(), 0, 250); 
          invalidate(); 
        } else if (event.getx() < getwidth() / 2) { 
          mscreenstate = screen_state_close; 
          mscroller.startscroll(getchildat(1).getscrollx(), 0, 
              -getchildat(1).getscrollx(), 0, 800); 
          invalidate(); 
        } else { 
          mscreenstate = screen_state_open; 
          mscroller 
              .startscroll( 
                  getchildat(1).getscrollx(), 
                  0, 
                  -(getwidth() 
                      - math.abs(getchildat(1) 
                          .getscrollx()) - 
 
                  mwidth), 0, 800); 
          invalidate(); 
        } 
      } 
      break; 
    } 
    return super.ontouchevent(event); 
  } 
 
  public void open() { 
    mtouchstate = mscroller.isfinished() ? touch_state_restart 
        : touch_state_scrolling; 
    if (mtouchstate == touch_state_restart) { 
      mscreenstate = screen_state_open; 
      mscroller.startscroll(getchildat(1).getscrollx(), 0, -(getwidth() 
          - math.abs(getchildat(1).getscrollx()) - 
 
      mwidth), 0, 800); 
      invalidate(); 
    } 
  } 
 
  //关闭当前的侧滑菜单,用view打开点击事件的页面 
  public void close(view view) { 
    mscreenstate = screen_state_close; 
    mscroller.startscroll(getchildat(1).getscrollx(), 0, -getchildat(1) 
        .getscrollx(), 0, 800); 
    invalidate(); 
    setcontentview(view); 
  } 
 
  public void computescroll() { 
    super.computescroll(); 
    if (mscroller.computescrolloffset()) { 
      getchildat(1).scrollto(mscroller.getcurrx(), mscroller.getcurry()); 
      postinvalidate(); 
    } else { 
      if (mscreenstate == screen_state_open) { 
        if (monugcdismisslistener != null) { 
          monugcdismisslistener.dismiss(); 
        } 
      } else if (mscreenstate == screen_state_close) { 
        if (monugcshowlistener != null) { 
          monugcshowlistener.show(); 
        } 
      } 
    } 
  } 
  private void obtainvelocitytracker(motionevent event) { 
    if (mvelocitytracker == null) { 
      mvelocitytracker = velocitytracker.obtain(); 
    } 
    mvelocitytracker.addmovement(event); 
  } 
  private void releasevelocitytracker() { 
    if (mvelocitytracker != null) { 
      mvelocitytracker.recycle(); 
      mvelocitytracker = null; 
    } 
  } 
  public int getscreenstate() { 
    return mscreenstate; 
  } 
  public void setcontentview(view view) { 
    removeviewat(1); 
    addview(view, 1, getlayoutparams()); 
  } 
  public interface onopenlistener { 
    public abstract void open(); 
  } 
  public interface oncloselistener { 
    public abstract void close(); 
  } 
  public interface onugcdismisslistener { 
    public abstract void dismiss(); 
  } 
  public interface onugcshowlistener { 
    public abstract void show(); 
  } 
  public void setonugcdismisslistener( 
      onugcdismisslistener onugcdismisslistener) { 
    monugcdismisslistener = onugcdismisslistener; 
  } 
  public void setonugcshowlistener(onugcshowlistener onugcshowlistener) { 
    monugcshowlistener = onugcshowlistener; 
  } 
} 

4、主界面mainactivity

package com.mmsx.activity;  
import com.mmsx.activity.sideslipmenu.onchangeviewlistener; 
import com.mmsx.activity.sideslipother.ondatalistener; 
import com.mmsx.base.flipperlayout; 
import com.mmsx.base.flipperlayout.onopenlistener; 
import com.mmsx.base.viewutil; 
import android.os.bundle; 
import android.app.activity; 
import android.view.viewgroup.layoutparams; 
import android.widget.toast; 
 
public class mainactivity extends activity implements onopenlistener{ 
 
  //侧滑主要控制类,设置跟布局 
  private flipperlayout mroot; 
  //侧滑的默认界面,主界面 
  private sidesliphome mhome; 
  //侧滑的菜单,进行选择的 
  private sideslipmenu msideslipmenu; 
  //其他菜单列表选择的效果 
  private sideslipother mother; 
  //退出时间间隔变量 
  private long mexittime; 
  //时间间隔2s 
  private static final int interval = 2000; 
  //侧滑菜单选中的item 
  private int mviewposition; 
  //侧滑传递的标题 
  private string mstrtitle; 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
     //创建容器,并设置全屏大小 
    mroot = new flipperlayout(this); 
    //布局的参数 
    layoutparams params = new layoutparams(layoutparams.fill_parent, 
        layoutparams.fill_parent); 
    mroot.setlayoutparams(params); 
    //创建菜单界面和内容首页界面,并添加到容器中,用于初始显示 
    mhome = new sidesliphome(this, this); 
    msideslipmenu = new sideslipmenu(this); 
    mroot.addview(msideslipmenu.getview(), params); 
    mroot.addview(mhome.getview(), params); 
    //设置跟布局 
    setcontentview(mroot); 
    //设置监听 
    setlistener(); 
  } 
 
  //设置监听 
  private void setlistener() { 
    mhome.setonopenlistener(this); 
     //监听菜单界面切换显示内容(onchangeviewlistener接口在sideslipmenu中定义) 
    msideslipmenu.setonchangeviewlistener(new onchangeviewlistener() { 
       
      public void onchangeview(int arg0) { 
        mviewposition = arg0; 
        mother = new sideslipother(mainactivity.this); 
        switch (arg0) { 
        case viewutil.home: 
          mroot.close(mhome.getview()); 
          break; 
        case viewutil.message: 
          mstrtitle = "消息"; 
          //设置数据接口监听 
          mother.setdatatitle(new datatitle()); 
          mroot.close(mother.getview()); 
          break; 
        case viewutil.friends: 
          mstrtitle = "好友"; 
          mother.setdatatitle(new datatitle()); 
          mroot.close(mother.getview()); 
          break; 
        case viewutil.photo: 
          mstrtitle = "照片"; 
          mother.setdatatitle(new datatitle()); 
          mroot.close(mother.getview()); 
          break; 
        case viewutil.viewed: 
          mstrtitle = "转帖"; 
          mother.setdatatitle(new datatitle()); 
          mroot.close(mother.getview()); 
          break; 
        case viewutil.gifts: 
          mstrtitle = "礼物"; 
          mother.setdatatitle(new datatitle()); 
          mroot.close(mother.getview()); 
          break; 
        case viewutil.recommend: 
          mstrtitle = "游戏"; 
          mother.setdatatitle(new datatitle()); 
          mroot.close(mother.getview()); 
          break; 
        case viewutil.lbs: 
          mstrtitle = "附近 "; 
          mother.setdatatitle(new datatitle()); 
          mroot.close(mother.getview()); 
          break; 
        default: 
          break; 
        } 
      } 
    }); 
  } 
   
  //传递数据到侧滑选中的页面 
  private class datatitle implements ondatalistener{ 
    @override 
    public string getdatatitle() { 
      return mstrtitle; 
    } 
     
  } 
 
  @override 
  public void open() { 
    if (mroot.getscreenstate() == flipperlayout.screen_state_close) { 
      mroot.open(); 
    } 
  } 
   
  /** 
   * 返回键监听 
   */ 
  public void onbackpressed() { 
    /** 
     * 如果界面的path菜单没有关闭时,先将path菜单关闭,否则则判断两次返回时间间隔,小于两秒则退出程序 
     */ 
    if (mroot.getscreenstate() == flipperlayout.screen_state_open) { 
      if (msideslipmenu.getugcisshowing()) { 
        msideslipmenu.closeugc(); 
      } else { 
        exit(); 
      } 
    } else { 
      switch (mviewposition) { 
      case viewutil.home: 
        if (mhome.getugcisshowing()) { 
          mhome.closeugc(); 
        } else { 
          exit(); 
        } 
        break; 
      default: 
        exit(); 
        break; 
      } 
 
    } 
 
  }   
  /** 
   * 判断两次返回时间间隔,小于两秒则退出程序 
   */ 
  private void exit() { 
    if (system.currenttimemillis() - mexittime > interval) { 
      toast.maketext(this, "再按一次返回键,可直接退出程序", toast.length_short).show(); 
      mexittime = system.currenttimemillis(); 
    } else { 
      finish(); 
      android.os.process.killprocess(android.os.process.mypid()); 
      system.exit(0); 
    } 
  } 
}

5、sidesliphome

package com.mmsx.activity; 
import com.mmsx.base.flipperlayout.onopenlistener; 
 
import android.app.activity; 
import android.content.context; 
import android.view.layoutinflater; 
import android.view.view; 
import android.widget.textview; 
 
public class sidesliphome { 
  private context mcontext; 
  private activity mactivity; 
  private view mhomeview; 
  private boolean mugcisshowing = false;  
  private onopenlistener monopenlistener; 
  public sidesliphome(context context, activity activity) { 
    mcontext = context; 
    mactivity = activity; 
    mhomeview = layoutinflater.from(context).inflate(r.layout.sideslip_home, null); 
     
    initui(); 
  } 
 
  private void initui() { 
    textview ivtitlename = (textview)mhomeview.findviewbyid(r.id.ivtitlename);  
    ivtitlename.settext("主页动态"); 
     
  } 
   
  public void setonopenlistener(onopenlistener onopenlistener) { 
    monopenlistener = onopenlistener; 
  } 
 
  public view getview() { 
    return mhomeview; 
  } 
   
  /** 
   * 获取path菜单显示状态 
   */ 
  public boolean getugcisshowing() { 
    return mugcisshowing; 
  } 
 
  /** 
   * 关闭path菜单 
   */ 
  public void closeugc() { 
    mugcisshowing = false; 
  } 
 
} 

好了,以上就是本文的全部叙述,希望大家喜欢。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网