Android开源库SlideMenu如何实现沉浸式效果

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22090073/article/details/60146899

SlideMenu是一个在Android上被广泛使用的开源库,它是一个仿照IOS左滑菜单开发的类似效果。 
SlideMenu开源库GuiHub地址如下: 
SlideMenu GitHub

在项目中导入SlideMenu有两种方式,一种是将SlideMenu作为Library库,然后在自己的项目中右键点击Properties–>android–>在右下方Library选项将开源库添加进来,点击apply即可;第二种方式是将SlideMenu项目中的lib包直接复制到我们的项目中(这里存在第三种方式,可以自己打Jar,略过不谈),之后如何开始利用SlideMenu添加菜单呢? 
第一步,我们一般可以写个自定义控件继承SlideMenu,其主要代码如下:


private final Activity activity;
    SlidingMenu localSlidingMenu;

    public MySlideMenu(Activity activity) {
        this.activity = activity;
    }

    public SlidingMenu initSlidingMenu() {
        localSlidingMenu = new SlidingMenu(activity);
        localSlidingMenu.setMode(SlidingMenu.LEFT);//设置左右滑菜单
        localSlidingMenu.setTouchModeAbove(SlidingMenu.SLIDING_WINDOW);//设置要使菜单滑动,触碰屏幕的范围
        //localSlidingMenu.setTouchModeBehind(SlidingMenu.SLIDING_CONTENT);
        localSlidingMenu.setShadowWidthRes(R.dimen.shadow_width);//设置阴影图片的宽度
        localSlidingMenu.setShadowDrawable(R.drawable.shadow);//设置阴影图片
        localSlidingMenu.setBehindOffsetRes(R.dimen.slidingmenu_offset);//SlidingMenu划出时主页面显示的剩余宽度
        localSlidingMenu.setFadeDegree(0.35F);//SlidingMenu滑动时的渐变程度
        localSlidingMenu.attachToActivity(activity, SlidingMenu.SLIDING_WINDOW);//使SlidingMenu附加在Activity右边
        localSlidingMenu.setMenu(R.layout.left_drawer_fragment);//设置menu的布局文件
        localSlidingMenu.setOnOpenedListener(new SlidingMenu.OnOpenedListener() {
                    public void onOpened() {

                    }
                });
        localSlidingMenu.setOnClosedListener(new OnClosedListener() {

            @Override
            public void onClosed() {
                // TODO Auto-generated method stub

            }
        });
        return localSlidingMenu;
    }

其中菜单的布局文件大家可以自己设置,之后在我们的Activity的OnCreate中添加如下代码:

    MySlideMenu slide=new MySlideMenu(this);
    slide.initSlidingMenu();

这样左滑菜单即可成功导入,效果如下(来自仿今日头条源码):



那么,实现沉浸式菜单栏该怎么做呢: 
在Activity设置了布局文件之后加入如下代码:

if (Environment.getInstance().getOSVersionCode() >= VERSION_CODES.KITKAT) {
            getWindow().addFlags(   WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(           WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }

因为沉浸式状态栏是在Android4.4才被Google引用的,所以需要先判断SDK的版本是否超过了KITKAT。在布局文件的代码中加入如下两句:

 android:clipToPadding="true"
 android:fitsSystemWindows="true"

这里是使得控件布局顶到状态栏去。 
那么在SlideMenu中加入沉浸式会是什么效果呢?请看下图:



图中显示,控件无法实现沉浸式效果。可真的是如此么?仔细观察可以发现,状态栏的颜色确实是改变了,而且变成了白色,那么说明状态栏是沉浸了的,只是下面的控件无法“顶”上去而已,那么该如何解决呢? 
通过扒SlideMenu的源码可知,SlideMenu是利用ViewGroup来作为ViewAbove和ViewBehind的容器,而这里的ViewAbove和ViewBehind就是分别代表我们的主界面布局文件和菜单布局文件。而通过查阅资料我们发现,沉浸式状态栏是仅仅支持Layout和TextView等几种控件的沉浸效果的,而且如果Layout里面的第一个控件为ImageView,沉浸效果也是无法实现的,所以,笔者这里提供两个解决方案: 
方案一:修改SlideMenu源码 
在ViewGroup中加入TextView或者其他控件作为顶部控件来实现,这里笔者并没有做过类似工作,所以可行性不敢保证,重点介绍第二种方案; 
方案二:曲线救国 
分析SlideMenu可知,SlideMenu本身是继承了RelativeLayout的,所以理所当然的它也可以在布局文件中作为view而存在,而这种自定义view是无法直接实现沉浸式效果的,那么,曲线救国的方式就来了,我们利用一个RelativeLayout包裹住该SlideMenu,然后在该View之前加入一个高度为1dp的TextView,这里只需把该TextView的Visibity设置为Gone即可不对应用产生任何影响。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/id_main_ly"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:clipToPadding="true"
            android:fitsSystemWindows="true"
            android:visibility="gone" />

        <com.zf.control.slidingmenu.lib.SlidingMenu
            xmlns:sliding="http://schemas.android.com/apk/res-auto"
            android:id="@+id/slidingmenulayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            sliding:behindOffset="0dp"
            sliding:behindScrollScale="1"
            sliding:fadeDegree="0.7"
            sliding:fadeEnabled="true"
            sliding:touchModeAbove="margin"
            sliding:viewAbove="@layout/activity_base" />
    </LinearLayout>

</RelativeLayout>

这里实现的效果是将整个View直接顶到了状态栏,很明显这不是我们需要的效果,那么我们可以得到状态栏的高度,之后设置title_bar的高度和PaddingTop属性即可解决,代码如下:

if (Environment.getInstance().getOSVersionCode() >= VERSION_CODES.KITKAT) {
            getWindow().addFlags(
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

            // 改变titlebar的高度
            int statusbarHeight = UIUtils.getStatusBarHeight(getWindow());
            RelativeLayout top_heads = (RelativeLayout) mLeftMenu.getContent()
                    .findViewById(R.id.top_head);
            int height = UIUtils.getMeasureHeightOnCreate(top_heads);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LayoutParams.MATCH_PARENT, height + statusbarHeight);
            top_heads.setLayoutParams(lp);
            top_heads.setPadding(0, statusbarHeight, 0, 0);
            mLeftMenu
                    .getMenu()
                    .findViewById(R.id.logout_layout)
                    .setPadding(0, UIUtils.getStatusBarHeight(getWindow()), 0,
                            0);
        }

最终实现的效果如下:




猜你喜欢

转载自blog.csdn.net/qq_22090073/article/details/60146899