安卓隱藏手機虛擬按鍵
阿新 • • 發佈:2019-02-03
我的實現思路是,通過監聽根佈局的檢視高度的變化,來判斷虛擬按鍵的隱藏和顯示
1. 在oncreate中View.getWidth和View.getHeight無法獲得一個view的高度和寬度,這是因為View元件佈局要在onResume回撥後完成。所以現在需要使用getViewTreeObserver().addOnGlobalLayoutListener()來獲得根佈局的高度。
2. OnGlobalLayoutListener 是ViewTreeObserver的內部類,當一個檢視樹的佈局發生改變時,可以被ViewTreeObserver監聽到,這是一個註冊監聽檢視樹的觀察者(observer),在檢視樹的全域性事件改變時得到通知。ViewTreeObserver不能直接例項化,而是通過getViewTreeObserver()獲得。
3. 獲取到當前佈局的高度和activity跟佈局的高度,進行對比
程式碼如下:
//隱藏虛擬按鍵 rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //比較Activity根佈局與當前佈局的大小 int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();if (heightDiff > 100) { //大小超過100時,一般為顯示虛擬鍵盤事件 rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } else { //大小小於100時,為不顯示虛擬鍵盤或虛擬鍵盤隱藏 rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); } } });
第一種方法存在一些問題,更完美的解決方案,簡單粗暴,請看下面的方法
第二種方法
- /**
-
* 隱藏虛擬按鍵,並且設定成全屏
- */
- private void hideBottomState(){
- if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT <19) { // lower api
- View v = this.getWindow().getDecorView();
- v.setSystemUiVisibility(View.GONE);
- } else if (Build.VERSION.SDK_INT >= 19) {
- //for new api versions.
- View decorView = getWindow().getDecorView();
- int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
- | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
- | View.SYSTEM_UI_FLAG_IMMERSIVE;
- decorView.setSystemUiVisibility(uiOptions);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
- }
- }
擴充套件功能
- /**
- * 檢查是否存在虛擬按鍵欄
- * @param context
- * @return
- */
- 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
- return !ViewConfiguration.get(context).hasPermanentMenuKey();
- }
- }
- /**
- * 判斷虛擬按鍵欄是否重寫
- * @return
- */
- 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;
-
}