最近在开发过程当中需要用到DrawerLayout来实现相关功能,在这个过程中经历了很多的尝试,为了能让在开发DrawerLayout的时候遇到问题的朋友少走弯路,特地将自己的经验分享出来。不再多说废话,我们在所有手机上要实现的效果如下图所示(在红米手机,Android 版本4.4上展示的效果):
如图点击江苏卫视的时候就会出现如下的抽屉效果:
布局代码比较长,我就不列出来了,在这里给大家展示一下我的布局结构:
根据这就可以看到我们的布局包含了两个FrameLayout,分别对应着图一图二的两张照片,其中在第二个FrameLayout中我们重点要设置如下属性用来实现抽屉从右向左打开的效果:
当然在这里我们还有很多布局细节没有列举出来,这里我们就来一步一步分析一下。一开始我这边实现的效果是这样的:
看到没,布局和菜单栏重叠了,布局代码如下:
你也想我在LinearLayout中也洗了marginTop属性啊,怎么没起作用呢?在这里直接说我的解决办法吧:
加入如图所示的代码就好了,那么下面这个属性到底是干什么用的呢?
android:fitsSystemWindows="true"
我们将光标放到这个属性上就可以看到如下提示:
翻译成英文意思就是:1、这是一个布尔值的内部属性值,作用是让当前视图在基于系统窗口如状态栏的基础上调整自己的布局。如果设置为true,就会调整当前布局的padding值以便给系统窗口流出空间。这个只会在我们当前的布局不是在一个非嵌套的activity当中时才会生效(一般我们使用的都不是嵌套的activity布局,因此暂时你不用理会最后一句话)。
拿上面的例子来解释,我们的标题栏和LinearLayout布局都在FrameLayout当中,但是他们两个重叠了,当我在FrameLayout当中加入了android:fitsSystemWindows="true"属性的时候,系统就会自动调整这两个布局的相对位置,所以你就看到了正常的效果。这也就是这个android:fitsSystemWindows="true"属性要加在FrameLayout当中,而不是其他地方的原因
然而根据自己的尝试,在这里我需要补充根据自己测试经验总结出来的第二个知识点:
2、android:fitsSystemWindows="true"该属性的作用是你当前的contentView是否会忽略掉与它同级的ToolBar MenuBar所占用的空间(如果有同级的ToolBar MenuBar的话),如果为true则忽略,否则不忽略
这句话很耐人寻味,这是什么意思?我们知道我现在布局当中的DrawerLayout所在的布局与ToolBar和还有MenuBar是在同一级,因此设置这个属性就会忽略ToolBar MenuBar所占用的空间,DrawerLayou里面的布局整体上移,结果就是下面这样子:
在这里还需要说明一点:这个上移的应当是ToolBar的距离,因为该在创建该Activity的时候我已经调用下面的代码去掉了标题栏:requestWindowFeature(Window.FEATURE_NO_TITLE)
这个时候可能有人要问了,那么我在FrameLayout当中设置该属性的时候为什么你的标题栏没有上移呢?
那是因为DrawerLayout所在的布局与ToolBar和还有MenuBar是在同一级,而FrameLayout是DrawerLayout的子控件,与ToolBar和还有MenuBar不在同一级,因此不会产生影响。
我们继续,当我点击第一个布局页面上的一个条目弹出抽屉的时候,在所有的手机上的效果显示没问题,却唯独在红米 Android 4.4的版本上上总是出现如下问题,即使设置了android:fitsSystemWindows="true"属性也不行:
最后在网上找到了解决方案,说需要对Android 4.4版本做单独处理,将整体布局向下移动一个状态栏的距离,具体代码如下:
// 通过反射获取状态栏高度
public static int getStatusBarHeight(Context context) {
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
return context.getResources().getDimensionPixelSize(x);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
然后在你打开抽屉的地方调用如下代码:
//打开抽屉
dlDsjkRight.openDrawer(GravityCompat.END);
//4.4系统下移一个状态栏高度
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT)
{
FrameLayout mDrawerLayout = (FrameLayout)findViewById(R.id.framlayou_tv_filter_end);
mDrawerLayout.setPadding(0, getStatusBarHeight(getApplicationContext()), 0, 0);
}
这样问题就能得到最终解决了,搞定。
如果文章当中有任何不正确的地方,还请广大读者纠正,非常感谢!
网友评论