作者:zf19921020
转载请注明出处
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);
}
最终实现的效果如下: