除了沉浸模式外,Android 4.4還有新的API,能使應用內的狀態欄和虛擬按鈕透明。其他更多的Android 4.4 APIs可以看這里。
如果要使應用內的狀態欄和虛擬按鈕變成透明有兩種方法。
一種是代碼方式:
1 Window window = getWindow(); 2 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 3 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
另外一種是使用兩個新的主題風格:
Theme.Holo.NoActionBar.TranslucentDecor和Theme.Holo.Light.NoActionBar.TranslucentDecor。
但是這種方式只支持Android4.4以上系統,所以為了保持兼容性,我們還是采用代碼方式比較好。只需要先判斷,如果是4.4以上系統才啟用代碼。
開啟后上下系統欄都透明了。
但是如果應用本身是帶有actionbar或者標題欄的話會就會變得比較尷尬,內容會在上面露出來。這個時候需要在布局文件里加入android:fitsSystemWindows="true"。
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:id="@+id/layout" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="#c8c8c8" > 6 7 <ListView 8 android:id="@+id/listview" 9 android:layout_width="match_parent" 10 android:layout_height="match_parent" /> 11 12 </RelativeLayout>
加入前 加入后
但是這樣的話內容就不能從透明的虛擬按鈕下穿過,沒原來那么好看。我們可以按照以前一樣把根布局設置一個高度為系統欄高度和ActionBar高度的內邊距就可以。
同時關於獲取ActionBar和狀態欄的高度,發現用原來的方法有時候會獲取的值為0。自己google找了一下,找到兩個前輩提供的獲取高度方法,獲取ActionBar高度,獲取狀態欄高度。
1 if (android.os.Build.VERSION.SDK_INT > 18) { 2 Window window = getWindow(); 3 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 4 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); 5 //設置根布局的內邊距 6 RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout); 7 relativeLayout.setPadding(0, getActionBarHeight()+getStatusBarHeight(), 0, 0); 8 }
1 // 獲取手機狀態欄高度 2 public int getStatusBarHeight() { 3 Class<?> c = null; 4 Object obj = null; 5 Field field = null; 6 int x = 0, statusBarHeight = 0; 7 try { 8 c = Class.forName("com.android.internal.R$dimen"); 9 obj = c.newInstance(); 10 field = c.getField("status_bar_height"); 11 x = Integer.parseInt(field.get(obj).toString()); 12 statusBarHeight = getResources().getDimensionPixelSize(x); 13 } catch (Exception e1) { 14 e1.printStackTrace(); 15 } 16 return statusBarHeight; 17 } 18 19 // 獲取ActionBar的高度 20 public int getActionBarHeight() { 21 TypedValue tv = new TypedValue(); 22 int actionBarHeight = 0; 23 if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))// 如果資源是存在的、有效的 24 { 25 actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); 26 } 27 return actionBarHeight; 28 }
設置后的效果
接下來,因為我自己寫的一些應用是暗色的主題的,會導致透明的狀態欄和ActionBar顏色不太協調。看到有一些應用是把狀態欄的顏色設置成和ActionBar一樣,這種解決方法也不錯。
具體是怎么實現的也不太清楚,我自己猜測寫了一個差不多狀態欄。我是直接在根視圖加入一個高度為狀態欄高度的TextView,背景設置為和ActionBar一樣。具體代碼如下:
1 // 創建TextView 2 TextView textView = new TextView(this); 3 LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, getStatusBarHeight()); 4 textView.setBackgroundColor(Color.parseColor("#3F9FE0")); 5 textView.setLayoutParams(lParams); 6 // 獲得根視圖並把TextView加進去。 7 ViewGroup view = (ViewGroup) getWindow().getDecorView(); 8 view.addView(textView);
在模擬器上看還行,但是在實際的手機當中總感覺ActionBar有點過大,所以我在背景色里加入了一些漸變,在實體手機中就比較好看一點,不會覺得ActionBar太寬了。
1 <?xml version="1.0" encoding="utf-8"?> 2 <shape xmlns:android="http://schemas.android.com/apk/res/android" > 3 <gradient android:startColor="#c8c8c8" 4 android:endColor="#3F9FE0" 5 android:angle="270" 6 android:type="linear"/> 7 8 </shape>