最近項目中遇到了華爲虛擬按鍵適配的問題,主頁是個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);