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