像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:

posted @ 2015-04-01 00:14  黑暗中的一盏明灯  阅读(6912)  评论(1编辑  收藏  举报