一般情况下,StatusBar显示在屏幕的顶部,NavigationBar显示在屏幕底部。但有些特殊情况。
在PhoneWindowManager.java中有相关的逻辑控制。
// SystemUI (status bar) layout policy
int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
// Allow the navigation bar to move on non-square small devices (phones).
mNavigationBarCanMove = width != height && shortSizeDp < 600;
@NavigationBarPosition private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
if (mNavigationBarCanMove && displayWidth > displayHeight) {
if (displayRotation == Surface.ROTATION_270) {
return NAV_BAR_LEFT;
} else {
return NAV_BAR_RIGHT;
}
}
return NAV_BAR_BOTTOM; }
举个例子:对于1920*1080的平台,[ro.sf.lcd_density]: [320]。
shortSizeDp = 540; longSizeDp = 960;
所以mNavigationBarCanMove = true。此时NavigationBar就会被移动到一侧显示。(注意:此时的导航栏的Layout oritation还是Landscape,而非Protrait,所以layout会被压缩到最右侧的一小部分空间显示,导致了UI异常)。
修改方式可以参考如下:
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -46,6 +46,7 @@ import android.util.Log;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
import android.view.Display;
+import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
@@ -965,10 +966,22 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
}
private void updateCurrentView() {
- final int rot = mDisplay.getRotation();
+ int rot = mDisplay.getRotation();
for (int i=0; i<4; i++) {
mRotatedViews[i].setVisibility(View.GONE);
}
+ // PATCH Start
+ int width = mDisplay.getWidth();
+ int heigth = mDisplay.getHeight();
+ int shortSize = width > heigth ? heigth : width;
+ int dp = shortSize * DisplayMetrics.DENSITY_DEFAULT / DisplayMetrics.DENSITY_DEVICE;
+ // mNavigationBarCanMove = width != height && shortSizeDp < 600; from PhoneWindowManager.java
+ // this situation, NavigationBar will be moved to LEFT/RIGHT side to show.
+ if (dp < 600 && width != heigth) {
+ rot = (rot + 1) % 4;
+ Log.d(TAG, "NavigationBar orient is workaround displayed");
+ }
+ // End
mCurrentView = mRotatedViews[rot];
mCurrentView.setVisibility(View.VISIBLE);
mNavigationInflaterView.setAlternativeOrder(rot == Surface.ROTATION_90);