zoukankan      html  css  js  c++  java
  • 怎样将DrawerLayout显示在ActionBar/Toolbar和status bar之间

    注意:下面效果实现方法仅仅在Android Lollipop下完毕,并如果你使用Theme.AppCompat.NoActionBar或者是Theme.AppCompat.Light.NoActionBar主题

    Material Design有个非常酷炫的效果,就是DrawerLayout隐藏的那一部分在拉开的时候,本应该被ActionBar和status bar挡住的那部分,如今能够露出来了。

    这样的效果已有人给出效果的实现方法了,可是对于非常多人来说还是不知道它是怎样实现的,所以这个这里先讲讲原理:

    在新的框架和支持包下,我们可以实现下面功能:首先使用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);
    

    最后

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


  • 相关阅读:
    面向对象编程总结Python
    垃圾收集器与内存分配策略
    自定义异常、异常处理注意点
    关于线程【一】——线程创建、停止、interrupted()和isInterrupted()区别
    Java内存区域
    HotSpot虚拟机对象
    异常——try、catch、finally、throw、throws
    关于线程【二】——线程同步和异步
    fillder代理调试
    新鲜出炉的Asp.Net MVC电子书
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7087000.html
Copyright © 2011-2022 走看看