Android 虛擬按鍵適配動態調整佈局

最近項目中遇到了華爲虛擬按鍵適配的問題,主頁是個RecylerView(如下圖),如果不做適配,在界面初始化完畢後,虛擬按鍵會遮擋頁面或者空出一些留白部分,針對這個問題上網找了些資料,總結了以下方法

首頁下部分是RecylerView

首頁下半部分是個RecylerView(針對適配)

監聽虛擬鍵的切換

  • 註冊系統廣播
getContentResolver().registerContentObserver(Settings.System.getUriFor("navigationbar_is_min"), true, mNavigationStatusObserver);
private ContentObserver mNavigationStatusObserver = new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
            int navigationBarIsMin = Settings.System.getInt(getContentResolver(),
                    "navigationbar_is_min", 0);
            if (navigationBarIsMin == 1) {//導航鍵隱藏了
                Log.e("導航鍵隱藏了", "-----");
                gridView_Home.getViewTreeObserver().addOnGlobalLayoutListener(HomeActivity.this);
            } else {//導航鍵顯示了
                Log.e("導航鍵顯示了", "-----");
                gridView_Home.getViewTreeObserver().addOnGlobalLayoutListener(HomeActivity.this);
            }
        }
    };

給View添加全局的佈局監聽器

可以看到當虛擬按鍵切換的時候我會調用view的getViewTreeObserver().addOnGlobalLayoutListener給view設置全局的佈局監聽器,用於獲取當前view可顯示的實際高度,然後根據高度動態設置子item的高度

  • 佈局監聽器的回調
    在回調中測量RecylerView可顯示的實際高度
 @Override
    public void onGlobalLayout() {
        refreshGridViewHeight();
    }

注意這個回調是會調用多次的,獲取完高度後要移除這個監聽,否則會造成界面卡頓

 private void refreshGridViewHeight() {
        gridView_Home.post(new Runnable() {
            @Override
            public void run() {
                //獲取到寬度和高度後,可用於計算
                int height = gridView_Home.getHeight();
                //根據屏幕高度計算單個菜單的高度,保證屏幕能被填滿
                final int itemHeight = height / 3 - 3;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        homeMenuAdapter.setIemtHeight(itemHeight);
                        gridView_Home.setAdapter(homeMenuAdapter);
                        mPresenter.refushGridData();
                        if (Build.VERSION.SDK_INT < 16) {
                            gridView_Home.getViewTreeObserver().removeGlobalOnLayoutListener(HomeActivity.this);
                        } else {
                            gridView_Home.getViewTreeObserver().removeOnGlobalLayoutListener(HomeActivity.this);
                        }
                    }
                });
            }
        });

這個移除佈局監聽的方法還要兼容低版本,所以要分情況,具體看代碼

  • 最後記得在Activity的onDestroy或界面銷燬的地方註銷剛纔設置的系統廣播接收者
    getContentResolver().unregisterContentObserver(mNavigationStatusObserver);

參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章