Android中沈浸式狀態欄的應用
阿新 • • 發佈:2017-10-31
ack get 實際應用 back ide real server 主界面 resources
在Android5.0版本後,谷歌公司為Android系統加入了很多新特性,刷新了Android用戶的體驗度。而其中的一個新特性就是沈浸式狀態欄。那麽問題來了,很多非移動端的小夥伴就要問了,什麽是沈浸式狀態欄?傳統的手機狀態欄是呈現出黑色條狀的,有的和手機主界面有很明顯的區別。這樣就在一定程度上犧牲了視覺寬度,界面面積變小。而沈浸式狀態欄將狀態欄的顏色變為透明,並將原有的布局沾滿了手機屏幕,使得狀態欄和手機布局內容融為一體。下面,我們來詳細的說明沈浸式狀態欄在項目中的實際應用。
要在當前的Activity界面實現沈浸式,首先我們要在oncreate方法中寫入如下代碼:
getWindow().requestFeature(Window.FEATURE_NO_TITLE); Window window= getWindow(); 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.TRANSPARENT); window.setNavigationBarColor(Color.TRANSPARENT); }
這樣代碼就可以實現沈浸式狀態。由於沈浸式狀態欄只支持5.0以上手機,所以我們在這裏進行了版本判斷。不過實際操作中,有小夥伴又遇到了新的問題。有些有虛擬按鍵的也被沈浸了,這個就會很郁悶了。我們的構思是布局中有一個黑色的view,在有虛擬按鍵的手機上顯示出來,並且高度與虛擬按鍵一致。具體操作如下。
檢查是否具有虛擬按鍵
public static boolean hasNavBar(Context context) { Resources res = context.getResources(); //這種方式一定要註意寫法要正確,內部應該是通過反射去調用的。 int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android"); if (resourceId != 0) { boolean hasNav = res.getBoolean(resourceId); // check override flag String sNavBarOverride = getNavBarOverride(); if ("1".equals(sNavBarOverride)) { hasNav = false; } else if ("0".equals(sNavBarOverride)) { hasNav = true; } return hasNav; } else { // fallback if (Build.VERSION.SDK_INT >= 14) { return !ViewConfiguration.get(context).hasPermanentMenuKey(); } else { return false; } } }
判斷虛擬按鍵欄是否重寫
private static String getNavBarOverride() { String sNavBarOverride = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { try { Class c = Class.forName("android.os.SystemProperties"); Method m = c.getDeclaredMethod("get", String.class); m.setAccessible(true); sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys"); } catch (Throwable e) { } } return sNavBarOverride; }
獲取虛擬按鍵欄高度
public static int getBottomStatusHeight(Context context) { int totalHeight = getDpi(context); int contentHeight = getScreenHeight(context); return totalHeight - contentHeight; }
獲取屏幕高度
public static int getScreenHeight(Context context) { WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.heightPixels; }
獲取屏幕原始尺寸高度,包括虛擬功能鍵高度
public static int getDpi(Context context) { int dpi = 0; WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); DisplayMetrics displayMetrics = new DisplayMetrics(); @SuppressWarnings("rawtypes") Class c; try { c = Class.forName("android.view.Display"); @SuppressWarnings("unchecked") Method method = c.getMethod("getRealMetrics", DisplayMetrics.class); method.invoke(display, displayMetrics); dpi = displayMetrics.heightPixels; } catch (Exception e) { e.printStackTrace(); } return dpi; }
代碼中設置布局中View的高度
if (hasNavBar(this)) { bottomView.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { // 當layout執行結束後回調此方法 @Override public void onGlobalLayout() { LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) bottomView.getLayoutParams(); params.height = getBottomStatusHeight(ActivityShopIndex.this); bottomView.setLayoutParams(params); bottomView.setVisibility(View.VISIBLE); } }); }
這樣我們就成功將虛擬按鍵欄也被沈浸的問題解決了。
作者 水木
Android中沈浸式狀態欄的應用