Android 打造完美的侧滑菜单/侧滑View控件

我的梦境 提交于 2019-12-02 12:43:10

概述

Android 打造完美的侧滑菜单/侧滑View控件,完全自定义实现,支持左右两个方向弹出,代码高度简洁流畅,兼容性高,控件实用方便.

详细

一.概述

在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上

咱们可以自己也写一个自定义的侧滑View控件,其实不难,主要涉及到以下几个要点:

1.对Android中Window类中的DecorView有所了解

2.对Scroller类实现平滑移动效果

3.自定义ViewGroup的实现

下面现在就来说说这里咱们实现侧滑View的基本思路吧,这里我采用的是自定义一个继承于RelativeLayout的控件叫做XCSlideView类吧。

首先从布局文件中inflater出来一个menuView,然后通过addView的方法,将该侧滑View添加到自定义的控件View中

怎么让XCSlideView 这个侧滑View 隐藏到屏幕之外呢?很简单通过ScrollTo方法,移动一个屏幕宽度的距离即可,这里以

左侧滑出为例吧,只需要这样 XCSlideView.this.scrollTo(mScreenWidth, 0);mScreenWidth是屏幕宽度。下面还要处理的就是底下的

半透明黑色的蒙层效果,这个其实就是一个View,然后设置半透明效果。这个当然简单了,关键是咱们让他显示在咱们的自定义侧滑View的下面呢,

这里咱们先给出DecorView的简单分析,方便下面介绍添加半透明View蒙层下:

二.演示效果图

 

 


三.代码实现过程解析

根据上面的概述,大家应该知道大概的思路了,下面我就给出自定义侧滑View类的核心代码:

1、自定义侧滑View用到的变量:

//侧滑方向-从哪侧滑出     public static enum Positon {         LEFT, RIGHT     }     private Context mContext;     private Activity mActivity;     private Scroller mScroller = null;     //侧滑菜单布局View     private View mMenuView;     //底部蒙层View     private View mMaskView;     private int mMenuWidth = 0;     //屏幕宽度     private int mScreenWidth = 0;     //是否在滑动中     private boolean mIsMoving = false;     //显示登录界面与否     private boolean mShow = false;     //滑动动画时间     private int mDuration = 600;     //缺省侧滑方向为左     private Positon mPositon = Positon.LEFT;

2、初始化创建自定义侧滑View:

**      * 创建侧滑菜单View      */     public static XCSlideView create(Activity activity) {         XCSlideView view = new XCSlideView(activity);         return view;     }     /**      * 创建侧滑菜单View      */     public static XCSlideView create(Activity activity, Positon positon) {         XCSlideView view = new XCSlideView(activity);         view.mPositon = positon;         return view;     }

3、创建半透明蒙层View,并添加到contentView中去

/**      * 创建 蒙层View并添加到contentView中      */     private void attachToContentView(Activity activity, Positon positon) {         mPositon = positon;         ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(android.R.id.content);         ViewGroup contentView = ((ViewGroup) contentFrameLayout.getChildAt(0));         mMaskView = new View(activity);         mMaskView.setBackgroundColor(mContext.getResources().getColor(R.color.mask_color));         contentView.addView(mMaskView, contentView.getLayoutParams());         mMaskView.setVisibility(View.GONE);         mMaskView.setClickable(true);         mMaskView.setOnClickListener(new OnClickListener() {             @Override             public void onClick(View view) {                 if (isShow()) {                     dismiss();                 }             }         });     }

4、设置侧滑菜单View,并添加到DectorView->LinearLayout->内容显示区域View(FrameLayout)中

/**      * 设置侧滑菜单View,并添加到DectorView->LinearLayout->内容显示区域View中      */     public void setMenuView(Activity activity, View view) {         mActivity = activity;         mMenuView = view;         LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);         addView(mMenuView, params);         mMenuView.post(new Runnable() {             @Override             public void run() {                 // TODO Auto-generated method stub                 mMenuWidth = mMenuView.getWidth();                 switch (mPositon) {                     case LEFT:                         XCSlideView.this.scrollTo(mScreenWidth, 0);                         break;                     case RIGHT:                         XCSlideView.this.scrollTo(-mScreenWidth, 0);                         break;                 }              }         });         ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(android.R.id.content);         ViewGroup contentView = contentFrameLayout;         contentView.addView(this);         FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) this.getLayoutParams();         switch (mPositon) {             case LEFT:                 layoutParams.gravity = Gravity.LEFT;                 layoutParams.leftMargin = 0;                 break;             case RIGHT:                 layoutParams.gravity = Gravity.RIGHT;                 layoutParams.rightMargin = 0;                 break;         }         TextView titleFrameLayout = (TextView) activity.findViewById(android.R.id.title);         if( titleFrameLayout != null){             layoutParams.topMargin = DensityUtil.getStatusBarHeight(mContext);         }         int flags =  mActivity.getWindow().getAttributes().flags;         int flag = (flags & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);         if(flag == WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS){             //说明状态栏使用沉浸式             layoutParams.topMargin = DensityUtil.getStatusBarHeight(mContext);         }         this.setLayoutParams(layoutParams);     }

5、处理自定义侧滑View的侧滑滑动和隐藏效果:

/**      * 显示侧滑菜单View      */     public void show(){         if(isShow() && !mIsMoving)             return;         switch (mPositon) {             case LEFT:                 startScroll(mMenuWidth, -mMenuWidth, mDuration);                 break;             case RIGHT:                 startScroll(-mMenuWidth, mMenuWidth, mDuration);                 break;         }         switchMaskView(true);         mShow = true;     }     /**      * 蒙层显示开关      */     private void switchMaskView(boolean bShow){         if(bShow){             mMaskView.setVisibility(View.VISIBLE);             Animation animation = new AlphaAnimation(0.0f, 1.0f);             animation.setDuration(mDuration);             mMaskView.startAnimation(animation);         }else{             mMaskView.setVisibility(View.GONE);         }     }     /**      * 关闭侧滑菜单View      */     public void dismiss() {         // TODO Auto-generated method stub         if(!isShow() && !mIsMoving)             return;         switch (mPositon) {             case LEFT:                 startScroll(XCSlideView.this.getScrollX(), mMenuWidth, mDuration);                 break;             case RIGHT:                 startScroll(XCSlideView.this.getScrollX(), -mMenuWidth, mDuration);                 break;         }         switchMaskView(false);         mShow = false;     }     public boolean isShow(){         return mShow;     }     @Override     public void computeScroll() {         // TODO Auto-generated method stub         if (mScroller.computeScrollOffset()) {             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());             // 更新界面             postInvalidate();             mIsMoving = true;          } else {             mIsMoving = false;         }         super.computeScroll();     }     /**      * 拖动移动      */     public void startScroll(int startX, int dx,int duration){         mIsMoving = true;         mScroller.startScroll(startX,0,dx,0,duration);         invalidate();     }


四.如何使用该自定义侧滑View控件

使用起来,比较简单,通过create方法创建一个侧滑VIew,然后通过setMenuView方法设置一个侧滑View进去,有需要设置

宽度的话, 通过setMenuWidth方法来设置即可,最后用show()方法滑出来就可以啦,使用起来是不是很方便?

private XCSlideView mSlideViewLeft; //屏幕宽度 private int mScreenWidth = 0; View menuViewLeft = LayoutInflater.from(mContext).inflate(R.layout.layout_slideview,null); mSlideViewLeft = XCSlideView.create(this, XCSlideView.Positon.LEFT); mSlideViewLeft.setMenuView(MainActivity.this, menuViewLeft); mSlideViewLeft.setMenuWidth(mScreenWidth * 7 / 9); Button left = (Button)findViewById(R.id.btn_left);         left.setOnClickListener(new View.OnClickListener() {              @Override             public void onClick(View v) {                 // TODO Auto-generated method stub                 if (!mSlideViewLeft.isShow())                     mSlideViewLeft.show();             }         });


五.项目代码结构图

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!