隨著全面屏的出現,Android廠商為了更高的屏占屏,紛紛拋棄實體按鍵的設計,轉而采用虛擬按鍵的方案。由于Android碎片化比較嚴重,各個廠商的不同機型的虛擬按鍵的樣式各不相同。如果我們對于虛擬按鍵不做處理,進入游戲,由于機型差異會有以下大概幾種問題。
-
虛擬按鍵背景大部分機型為黑色,對整個游戲的界面效果來說是不太友好的
示例一.jpeg -
部分機型的虛擬按鍵區域提供隱藏虛擬按鍵的入口,當點擊時,隱藏按鍵的功能鍵隱藏,當虛擬按鍵的區域并不會騰出以讓游戲界面自動填充,導致右邊會出現一塊黑邊
示例二.jpeg 部分機型的在相關操作下,虛擬按鍵會與游戲界面重合,導致游戲界面重合部分是無法正常響應事件
解決方案
針對以上問題,大概有兩種解決方案
- 保留虛擬按鍵,統一定制虛擬按鍵的樣式與顏色
- 隱藏虛擬按鍵
統一定制虛擬按鍵的樣式與顏色
在Window類中有一個方法可以設置虛擬按鍵的背景顏色
public abstract void setNavigationBarColor(@ColorInt int color);
Window有一個子類PhoneWindow它實現了父類所有的抽象方法
public void setNavigationBarColor(int color) {
mNavigationBarColor = color;
mForcedNavigationBarColor = true;
if (mDecor != null) {
mDecor.updateColorViews(null, false /* animate */);
mDecor.updateNavigationGuardColor();
}
}
android相關的組件getWindow()獲取的基本上是PhoneWindow的實例,相關的擴展內容可以參考activity的渲染機制
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(Color.parseColor("#1bb5d7"));
}
隱藏虛擬按鍵
這個方法的思路是隱藏虛擬按鍵,并且把虛擬按鍵的空間作為展示區域。具體的代碼實現:
public static void hideBottomUI(View view) {
int uiFlags = 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
if( android.os.Build.VERSION.SDK_INT >= 19 ){
uiFlags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; //View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY: hide navigation bars - compatibility: building API level is lower thatn 19, use magic number directly for higher API target level
} else {
uiFlags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
view.setSystemUiVisibility(uiFlags);
}
為了解決,虛擬按鍵彈出,無法再次隱藏的問題,我們額外做一道處理。
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int arg0) {
// TODO Auto-generated method stub
hideBottomUI(getWindow().getDecorView());
}
});
如果工程中activity比較多,個人建議創建一個baseAct,并且實現相關的邏輯。同時在使用的過程中有幾個要注意的點。
- 該方法的調用時機與實現
在對對應的組件添加對應的隱藏虛擬按鍵的邏輯時,特別要注意理解對應組件的渲染機制。hideBottomUI()所傳的參數不一定就是getWindow().getDecorView(),要結合具體的組件進行分析。組件渲染方式的不同,該方案具體調用的時機與所傳的參數也會有所差異,這里我就不一一分析。具體的可以參考Android對話框Dialog,PopupWindow,Toast的實現機制 - 對于大部分的視圖組件都需要加上相關的邏輯處理
很多時候大家很容易僅僅針對activity做相關的處理,而大多數時候我們的應用中會存在很多的視圖組件,為了更好的應用體驗,我們應該都對其做對應的處理。例如比較常見的dialog,PopupWindow等。
對于第一種方案來說,保留虛擬按鍵的原因主要是從用戶習慣來說,因為很多用戶已經習慣了虛擬按鍵的存在,他們能夠很方便找到切換到后臺的入口,或者呼出多任務。最開始采用隱藏虛擬按鍵的方案時,用戶是需要右滑屏幕呼出虛擬按鍵的。多了這一步操作,改變了原有用戶的使用習慣。