一、概述

  在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蒙层下:

下面是对上面这张图的解释:

1、DecorView为整个Window界面的最顶层View。

2、DecorView只有一个子元素为LinearLayout。代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。

3、LinearLayout里有两个FrameLayout子元素。

(20)为标题栏显示界面。只有一个TextView显示应用的名称。也可以自定义标题栏,载入后的自定义标题栏View将加入FrameLayout中。

(21)为内容栏显示界面。就是setContentView()方法载入的布局界面,加入其中。

有了上面的DecorVIew知识背景,现在就来说说 怎么添加蒙层View和将自定义侧滑View添加到Activity的DecorView中,首先把蒙层View添加到

(31)customView中去,然后将自定义侧滑View添加到 (21)FrameLayout中去,至于为什么要这样,是因为考虑到自定义侧滑View不一定是宽度为

屏幕宽度,所以才这么做,而且也方面处理有无标题栏,有无采用沉浸式状态栏设计等情况。

二、自定义侧滑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();            }        });

四、源码下载:

源码下载:http://download.csdn.net/detail/jczmdeveloper/9119423

GitHub地址:https://github.com/jczmdeveloper/XCSlideView

真题园网http://www.zhentiyuan.com

更多相关文章

  1. Android相机、相册获取图片显示并保存到SD卡
  2. Android中基类BaseActivity的设计与实现
  3. Android中添加万普广告墙、推送广告等
  4. android launcher 视频插件滚动bug
  5. Android实现图片宽度100%ImageView宽度且高度按比例自动伸缩
  6. Android可循环显示图像的Android(安卓)Gallery组件用法实例
  7. Android学习随笔之使用限定符
  8. 一文学会所有 Android(安卓)TextView 属性,妈妈再也不担心我的代
  9. android软键盘上添加一个按钮

随机推荐

  1. 对android:screenOrientation及android:c
  2. iphone OS、Android、Blackberry OS与Pal
  3. Android(安卓)网络管家ConnectivityManag
  4. android中ADT和SDK的关系
  5. Android Service待机/睡眠时运行
  6. Ionic 简单操作
  7. android service 学习
  8. 新手android 开发 错误集锦(持续更新中)
  9. android flutter 混合开发(配置篇)
  10. android中控件点击两次才响应onclick方法