標籤:解決 android5 action bar height 頁面 div turn 擷取
前言:
Android 4.4之後Google提供了沈浸式全屏體驗, 在沈浸式全螢幕模式下, 狀態列、 虛擬按鍵動態隱藏, 應用可以使用完整的螢幕空間, 按照 Google 的說法, 給使用者一種 身臨其境 的體驗。而Android 5.0之後Google又提出了 ColorPalette 的概念,讓開發人員可以自己設定系統地區的顏色,使整個 App 的顏色風格和系統的顏色風格保持統一。今天學習總結一下如何?Android 4.4以上全屏沈浸式透明狀態列效果。先看下預期效果:
首先現分清楚哪部分是狀態列,哪部分是導覽列
狀態列StatusBar如下
導覽列NavigationBar如下
如何?? 1.)首先實現全屏
第一種:繼承主題特定主題
在Android API 19以上可以使用****.TranslucentDecor***有關的主題,內建相應半透明效果,Theme.Holo.NoActionBar.TranslucentDecor和Theme.Holo.Light.NoActionBar.TranslucentDecor兩種主題為新增加的,所以要建立values-v19檔案夾並建立styles檔案添加如下代碼
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.NoActionBar.TranslucentDecor"> <!-- Customize your theme here. --> </style>
第二種:在activity中採用代碼的方式
Android 4.4以上可以添加如下代碼
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//透明狀態列window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明導覽列window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);}
Android 5.0 以上也可以使用下面的代碼實現全屏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);}
全屏效果
不難發現此時狀態列佔有的位置消失,和app的布局疊在一起了,接下來解決這個問題
2.)解決狀態欄佔位問題
第一種:主題添加如下設定
<item name="android:fitsSystemWindows">true</item>
第二種:activity layout根目錄添加下面代碼
android:fitsSystemWindows="true"
第三種:通過Java代碼設定
rootview.setFitsSystemWindows(true);
fitsSystemWindows只作用在sdk>=19的系統上就是高於4.4的系統,這個屬性可以給任何view設定,只要設定了這個屬性此view的所有padding屬性失效.只有在設定了透明狀態列(StatusBar)或者導覽列(NavigationBar)此屬性才會生效,
如果上述設定了狀態列和導覽列為透明的話,相當於對該View自動添加一個值等於狀態列高度的paddingTop,和等於導覽列高度的paddingBottom,效果如下
3.)狀態列導覽列設定背景色
4.4以上的可以採用修改contentView的背景色,或者動態添加一個view到contentView上
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //透明狀態列 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //透明導覽列 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); //設定contentview為fitsSystemWindows ViewGroup contentView = (ViewGroup) findViewById(android.R.id.content); View childAt = contentView.getChildAt(0); if (childAt != null) { childAt.setFitsSystemWindows(true); } //給statusbar著色 View view = new View(this); view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(this))); view.setBackgroundColor(color); contentView.addView(view); }
動態擷取StatusBarHeight函數如下
/** * 擷取狀態列高度 * * @param context context * @return 狀態列高度 */ private static int getStatusBarHeight(Context context) { // 獲得狀態列高度 int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return context.getResources().getDimensionPixelSize(resourceId); }
動態擷取NavigationBarHeight函數如下
/** * 擷取導覽列高度 * * @param context context * @return 導覽列高度 */ public static int getNavigationBarHeight(Context context) { int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); return context.getResources().getDimensionPixelSize(resourceId); }
然後Android5.0以上Google提供了新的api可以更新狀態列和導覽列的背景色
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //設定狀態列顏色 window.setStatusBarColor(color); //設定導覽列顏色 window.setNavigationBarColor(color); ViewGroup contentView = ((ViewGroup) findViewById(android.R.id.content)); View childAt = contentView.getChildAt(0); if (childAt != null) { childAt.setFitsSystemWindows(true); }// contentView.setPadding(0, getStatusBarHeight(this), 0, 0); }
這樣總體效果就實現了
4.)貼出整體java代碼實現方式
private void initWindows() { Window window = getWindow(); int color = getResources().getColor(android.R.color.holo_blue_light); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //設定狀態列顏色 window.setStatusBarColor(color); //設定導覽列顏色 window.setNavigationBarColor(color); ViewGroup contentView = ((ViewGroup) findViewById(android.R.id.content)); View childAt = contentView.getChildAt(0); if (childAt != null) { childAt.setFitsSystemWindows(true); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //透明狀態列 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //透明導覽列 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); //設定contentview為fitsSystemWindows ViewGroup contentView = (ViewGroup) findViewById(android.R.id.content); View childAt = contentView.getChildAt(0); if (childAt != null) { childAt.setFitsSystemWindows(true); } //給statusbar著色 View view = new View(this); view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(this))); view.setBackgroundColor(color); contentView.addView(view); } }總結:
我這裡為了更加明顯的顯示效果所以狀態列背景色和標題列顏色不一致,在實際的開發中一般情況下我們都會設定成統一的顏色,在視覺上感覺整個頁面更加統一,讓使用者真正沉浸在app中。
Android UI體驗之全屏沈浸式透明狀態列效果