zoukankan      html  css  js  c++  java
  • 像Google Play一样让DrawerLayout拉出的抽屉在透明系统状态栏和工具栏(ToolBar)之间。

    最近想实现和Google Play一样的侧边栏。拉出的抽屉在透明的状态栏和ActionBar之间。

    看到透明的状态栏就想起我去年写的一篇在Android4.4上开启透明状态栏的博客,在这里http://www.cnblogs.com/zhengxt/p/3536905.html。

    尝试下看行不行,新建个项目后在res文件下创建多一个values-v19来放Android4.4以上系统使用的样式。

    然后把values里面的style文件拷贝到vaules-v19里,再添加一条<item name="android:windowTranslucentStatus">true</item>来开启透明状态栏。

     1 <resources>
     2 
     3     <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
     4         <item name="windowActionBar">false</item>
     5         <item name="colorPrimary">@color/material_indigo_500</item>
     6         <item name="colorPrimaryDark">@color/material_indigo_700</item>
     7         <item name="colorAccent">@color/material_indigo_a200</item>
     8         <item name="android:windowTranslucentStatus">true</item>
     9     </style>
    10 
    11 </resources>

    然后创建DrawerLayout和ToolBar,为什么不用ActionBar而用ToolBar?因为ActionBar不属于Window内的元素,DrawerLayout拉出来的抽屉会始终被覆盖。但是我们用ToolBar就不一样了,

    ToolBar是要放在布局里的,抽屉拉出来后就会压在ToolBar上,这样才能达到我们想要的目的。而且ToolBar是AppCompat-V7包在21版本提供的一个更灵活的的工具栏,用来代替ActionBar。

    创建完后运行APP,果然能实现透明的状态栏。不过这样Theme里用colorPrimaryDark设置的状态栏颜色就没了。下面就需要我们自己给状态栏下方染上颜色,达到Google Play那样的效果。

        

    考虑在ToolBar上方加入一个View,然后给它设置一个和ToolBar一样的背景色就可以。但是这样太麻烦了,不如我们自定义一个ViewGroup来实现,需要用到的地方就使用这个ViewGroup作为根布局。

    然后就继承自FrameLayout来实现一个StatusBarColorLayout吧。

     1 /**
     2  * Description:
     3  * User: ZhengXingtian(lan4627@Gmail.com)
     4  * Date: 2015-03-31
     5  * Time: 23:55
     6  * Version: 1.0
     7  */
     8 public class StatusBarColorLayout extends FrameLayout{
     9 
    10     public StatusBarColorLayout(Context context) {
    11         super(context);
    12         init(context);
    13     }
    14 
    15     public StatusBarColorLayout(Context context, AttributeSet attrs) {
    16         super(context, attrs);
    17         init(context);
    18     }
    19 
    20     public StatusBarColorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    21         super(context, attrs, defStyleAttr);
    22         init(context);
    23     }
    24 
    25     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    26     public StatusBarColorLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    27         super(context, attrs, defStyleAttr, defStyleRes);
    28         init(context);
    29     }
    30 
    31     private Rect mStatusBarRect;
    32     private Paint mStatusBarColorPaint;
    33     private int mStatusBarHeight;
    34 
    35     private void init(Context context){
    36         // 让ToolBar处于系统状态栏下方
    37         setFitsSystemWindows(true);
    38         // 设置画笔
    39         mStatusBarColorPaint = new Paint();
    40         mStatusBarColorPaint.setColor(getThemeColor(context, R.attr.colorPrimary));
    41         mStatusBarColorPaint.setAntiAlias(true);
    42         mStatusBarColorPaint.setStyle(Paint.Style.FILL);
    43 
    44         mStatusBarRect = new Rect();
    45 
    46         mStatusBarHeight = getStatusBarHeight(context);
    47     }
    48 
    49     @Override
    50     protected void dispatchDraw(Canvas canvas) {
    51         // 要绘制的区域
    52         mStatusBarRect.set(getLeft(), getTop(), getRight(), mStatusBarHeight);
    53         // 绘制系统状态栏颜色
    54         canvas.drawRect(mStatusBarRect, mStatusBarColorPaint);
    55         super.dispatchDraw(canvas);
    56     }
    57 
    58     /**
    59      *  获取系统状态栏高度
    60      * @param context
    61      * @return
    62      */
    63     public int getStatusBarHeight(Context context) {
    64         Class<?> c = null;
    65         Object obj = null;
    66         Field field = null;
    67         int x = 0, statusBarHeight = 0;
    68         try {
    69             c = Class.forName("com.android.internal.R$dimen");
    70             obj = c.newInstance();
    71             field = c.getField("status_bar_height");
    72             x = Integer.parseInt(field.get(obj).toString());
    73             statusBarHeight = context.getResources().getDimensionPixelSize(x);
    74         } catch (Exception e) {
    75             e.printStackTrace();
    76         }
    77         return statusBarHeight;
    78     }
    79 
    80     /**
    81      *  获取当前主题里的颜色
    82      * @param context
    83      * @param resId
    84      * @return
    85      */
    86     public int getThemeColor(Context context, int resId){
    87         TypedValue value = new TypedValue();
    88         context.getTheme().resolveAttribute(resId, value, true);
    89         return value.data;
    90     }
    91 }

    然后在项目里使用就可以了。使用的代码如下:

     1 public class MainActivity extends ActionBarActivity {
     2 
     3     private ListView mDrawerListView;
     4 
     5     @Override
     6     protected void onCreate(Bundle savedInstanceState) {
     7         super.onCreate(savedInstanceState);
     8         setContentView(R.layout.activity_main);
     9         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    10         setSupportActionBar(toolbar);
    11         setListView();
    12     }
    13 
    14     private void setListView(){
    15         mDrawerListView = (ListView) findViewById(R.id.navigation_drawer);
    16         mDrawerListView.setAdapter(new ArrayAdapter<String>(
    17                 this,
    18                 android.R.layout.simple_list_item_activated_1,
    19                 android.R.id.text1,
    20                 new String[]{
    21                         getString(R.string.title_section1),
    22                         getString(R.string.title_section2),
    23                         getString(R.string.title_section3),
    24                 }));
    25     }
    26 
    27 }
     1 <android.support.v4.widget.DrawerLayout
     2     xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:id="@+id/drawer_layout"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     tools:context=".MainActivity">
     8 
     9     <com.zxtcode.myapplication.StatusBarColorLayout
    10         android:id="@+id/container"
    11         android:layout_width="match_parent"
    12         android:layout_height="match_parent">
    13 
    14         <android.support.v7.widget.Toolbar
    15             android:id="@+id/toolbar"
    16             android:layout_width="match_parent"
    17             android:layout_height="wrap_content"
    18             android:background="?attr/colorPrimary"
    19             android:minHeight="?attr/actionBarSize" />
    20 
    21     </com.zxtcode.myapplication.StatusBarColorLayout>
    22 
    23     <ListView android:id="@+id/navigation_drawer"
    24               android:layout_width="@dimen/navigation_drawer_width"
    25               android:layout_height="match_parent"
    26               android:layout_gravity="start"
    27               android:choiceMode="singleChoice"
    28               android:divider="@android:color/transparent"
    29               android:dividerHeight="0dp"
    30               android:background="#bbbb"/>
    31 
    32 
    33 
    34 </android.support.v4.widget.DrawerLayout>

    在Android5.1下的效果:

        

    在Android4.4下使用是这样子的:

      

    该效果依赖于4.4新增的API:windowTranslucentStatus。所以在低版本的Android下是无效果的,例如4.1:

  • 相关阅读:
    javaDoc 注释规范
    [阿里云] 如何 开放云主机 非80 端口?
    [Go] 跨平台文件系统监控工具 fsnotify 应用举例
    如何利用 jQuery 修改 css 中带有 !important 的样式属性?
    code.google.com/p/log4go 下载失败
    [Go] ok 判断 汇总
    [Go] 编码规范
    《Go语言实战》摘录:7.3 并发模式
    《Go语言实战》摘录:7.2 并发模式
    《Go语言实战》摘录:7.1 并发模式
  • 原文地址:https://www.cnblogs.com/zhengxt/p/4382550.html
Copyright © 2011-2022 走看看