最近想實現和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: