美文网首页androidAndroid开发随笔Android开发
如何将DrawerLayout显示在ActionBar/Tool

如何将DrawerLayout显示在ActionBar/Tool

作者: SoloHo | 来源:发表于2014-12-12 18:53 被阅读6523次

注意:以下效果实现方法只在Android Lollipop下完成,
并假设你使用Theme.AppCompat.NoActionBar,
或者是Theme.AppCompat.Light.NoActionBar主题

Material Design有个很酷炫的效果,就是DrawerLayout隐藏的那一部分在拉开的时候,本应该被ActionBar和status bar挡住的那部分,现在可以露出来了。

20141212_1.png

这种效果已有人给出效果的实现方法了,但是对于很多人来说还是不知道它是如何实现的,所以这个这里先讲讲原理:

在新的框架和支持包下,我们可以实现以下功能:首先使用Toolbar来代替ActionBar,这样我们就能够把ActionBar嵌入到我们的View体系中,然后我们"禁用"系统的status bar,由DrawerLayout来处理status bar,最后抽屉部分往上移,或者裁剪掉status bar那一部分。

控制status bar

在你的values-v21里面添加新的主题,并设置一下属性:

values-v21/themes.xml

<style name="AppTheme">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

这里解释一下:

windowDrawsSystemBarBackgrounds,将它设置为true,系统将在你的window里面绘制status bar,默认为TRUE,之所以要写出来是因为你的theme有可能是继承过来的,确保为true。(在这里小插曲一下,因调试时,总以为注释了这段代码就以为是false,程序员思维害苦了我。另外从命名来看,Android把它称为system bar,可能是为了与能被我们处理的status bar区分开而做的改变。)

statusBarColor设置为透明是因为我们不再需要系统的status bar,因为我们无法控制它的位置,后面我们将交由DrawerLayout来处理。

使用DrawerLayout

首先,你的布局文件应该是和这个类似的:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Your normal content view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- We use a Toolbar so that our drawer can be displayed
             in front of the action bar -->
        <android.support.v7.widget.Toolbar  
            android:id="@+id/my_awesome_toolbar"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary" />

        <!-- The rest of your content view -->

    </LinearLayout>

    <!-- The navigation drawer -->
    <ScrimInsetsFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="304dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:background="@android:color/white"
        android:elevation="10dp"
        android:fitsSystemWindows="true"
        app:insetForeground="#4000">

        <!-- Your drawer content -->

    </ScrimInsetsFrameLayout>

</android.support.v4.widget.DrawerLayout>

在这里布局里面我们用到了一个的开源类ScrimInsetsFrameLayout,它的主要作用就是利用fitsSystemWindows的回调方法fitSystemWindows(Rect insets)来获取status bar的大小,然后调整画布以达到去掉status bar的效果,所以我们需要在ScrimInsetsFrameLayout下设置fitsSystemWindows为true。当然你也可以不使用这个类,而改用layout_marginTop属性来达到效果。

insetForeground这个属性是ScrimInsetsFrameLayout自带的,表示插入区域的前景色,我们设置为带透明的黑色#4000。别忘了使用这个属性需要添加如下代码到attrs.xml里:

values/attrs.xml

<declare-styleable name="ScrimInsetsView">
    <attr name="insetForeground" format="reference|color" />
</declare-styleable>

自此,我们已经实现了将DrawerLayout抽屉的那一部分显示在Toolbar和system bar(为了和下面的status bar区分,我们称为system bar)之间了,可是system bar的颜色被我们设置了透明,所以我们接下来要改变status bar的颜色。

改变status bar的颜色

你可能已经注意到刚才的布局里面DrawerLayoutfitsSystemWindows属性设置了为true,这是因为我们要在代码里面使用了DrawerLayout设置status bar颜色的方法:

// 在这里我们获取了主题暗色,并设置了status bar的颜色
TypedValue typedValue = new TypedValue();
        getTheme().resolveAttribute(R.attr.colorPrimaryDark, typedValue, true);
int color = typedValue.data;

// 注意setStatusBarBackgroundColor方法需要你将fitsSystemWindows设置为true才会生效
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.my_drawer_layout);
        drawerLayout.setStatusBarBackgroundColor(color);

有关获取attr属性值的方法,可以看我另外一篇文章,点这里

使用Toolbar来代替ActionBar

在代码里面这样设置:

Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);

最后

赶紧看看你出来的效果是不是和上面的一样?为了实现这一点效果并理解它,真要认真琢磨一下,最后感谢你的阅读到这里。

转载请附上本文地址

相关文章

网友评论

  • 自己找知己:问下楼主,DrawerLayout+toolbar 在api19,也就是。4.4的系统中适配过status bar的颜色吗,我这边有点问题。总是不能很好的适配。想请教一下。
  • SoloHo:@ENDPOINT 具体哪个效果?ObservableScrollView是需要继承,我自己不推荐,实现原理可以参考。
  • f4ae36d0abfc:get 了~~大神的分享很好

本文标题:如何将DrawerLayout显示在ActionBar/Tool

本文链接:https://www.haomeiwen.com/subject/xqnntttx.html