广

android开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    代码分析Android实现侧滑菜单

    2018-05-07 10:25:08 次阅读 稿源:互联网
    广告

    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;   }  } 

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

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告