问题描述:
当系统SW < 600时, 会出现, 状态栏的导航键(NavigationBar)在横屏的时候会显示在界面右边
见源码.
@Override
public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight,
int displayRotation) {
mUnrestrictedScreenLeft = mUnrestrictedScreenTop = 0;
mUnrestrictedScreenWidth = displayWidth;
mUnrestrictedScreenHeight = displayHeight;
mRestrictedScreenLeft = mRestrictedScreenTop = 0;
mRestrictedScreenWidth = displayWidth;
mRestrictedScreenHeight = displayHeight;
mDockLeft = mContentLeft = mStableLeft = mStableFullscreenLeft
= mSystemLeft = mCurLeft = 0;
mDockTop = mContentTop = mStableTop = mStableFullscreenTop
= mSystemTop = mCurTop = 0;
mDockRight = mContentRight = mStableRight = mStableFullscreenRight
= mSystemRight = mCurRight = displayWidth;
mDockBottom = mContentBottom = mStableBottom = mStableFullscreenBottom
= mSystemBottom = mCurBottom = displayHeight;
mDockLayer = 0x10000000;
mStatusBarLayer = -1;
// start with the current dock rect, which will be (0,0,displayWidth,displayHeight)
final Rect pf = mTmpParentFrame;
final Rect df = mTmpDisplayFrame;
final Rect vf = mTmpVisibleFrame;
pf.left = df.left = vf.left = mDockLeft;
pf.top = df.top = vf.top = mDockTop;
pf.right = df.right = vf.right = mDockRight;
pf.bottom = df.bottom = vf.bottom = mDockBottom;
if (isDefaultDisplay) {
// For purposes of putting out fake window up to steal focus, we will
// drive nav being hidden only by whether it is requested.
boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
// When the navigation bar isn't visible, we put up a fake
// input window to catch all touch events. This way we can
// detect when the user presses anywhere to bring back the nav
// bar and ensure the application doesn't see the event.
if (navVisible) {
if (mHideNavFakeWindow != null) {
mHideNavFakeWindow.dismiss();
mHideNavFakeWindow = null;
}
} else if (mHideNavFakeWindow == null) {
mHideNavFakeWindow = mWindowManagerFuncs.addFakeWindow(
mHandler.getLooper(), mHideNavInputEventReceiverFactory,
"hidden nav", WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER,
0, false, false, true);
}
// For purposes of positioning and showing the nav bar, if we have
// decided that it can't be hidden (because of the screen aspect ratio),
// then take that into account.
navVisible |= !mCanHideNavigationBar;
if (mFocusedWindow != null) {
final int fl = mFocusedWindow.getAttrs().flags;
if ((fl & View.SYSTEM_UI_FLAG_SHOW_FULLSCREEN) != 0) {
navVisible = false;
}
}
if (mNavigationBar != null && ((mLastSystemUiFlags & View.SYSTEM_UI_FLAG_SHOW_FULLSCREEN) == 0)) {
// Force the navigation bar to its appropriate place and
// size. We need to do this directly, instead of relying on
// it to bubble up from the nav bar, because this needs to
// change atomically with screen rotations.
mNavigationBarOnBottom = (!mNavigationBarCanMove || displayWidth < displayHeight);//关键位置
if (mNavigationBarOnBottom) {
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
int top = displayHeight - mNavigationBarHeightForRotation[displayRotation];
mTmpNavigationFrame.set(0, top, displayWidth, displayHeight);
mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top;
if (navVisible) {
mNavigationBar.showLw(true);
mDockBottom = mTmpNavigationFrame.top;
mRestrictedScreenHeight = mDockBottom - mDockTop;
} else {
// We currently want to hide the navigation UI.
mNavigationBar.hideLw(true);
}
if (navVisible && !mNavigationBar.isAnimatingLw()) {
// If the nav bar is currently requested to be visible,
// and not in the process of animating on or off, then
// we can tell the app that it is covered by it.
mSystemBottom = mTmpNavigationFrame.top;
}
} else {
// Landscape screen; nav bar goes to the right.
int left = displayWidth - mNavigationBarWidthForRotation[displayRotation];
mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight);
mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left;
if (navVisible) {
mNavigationBar.showLw(true);
mDockRight = mTmpNavigationFrame.left;
mRestrictedScreenWidth = mDockRight - mDockLeft;
} else {
// We currently want to hide the navigation UI.
mNavigationBar.hideLw(true);
}
if (navVisible && !mNavigationBar.isAnimatingLw()) {
// If the nav bar is currently requested to be visible,
// and not in the process of animating on or off, then
// we can tell the app that it is covered by it.
mSystemRight = mTmpNavigationFrame.left;
}
}
// Make sure the content and current rectangles are updated to
// account for the restrictions from the navigation bar.
mContentTop = mCurTop = mDockTop;
mContentBottom = mCurBottom = mDockBottom;
mContentLeft = mCurLeft = mDockLeft;
mContentRight = mCurRight = mDockRight;
mStatusBarLayer = mNavigationBar.getSurfaceLayer();
// And compute the final frame.
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame);
if (DEBUG_LAYOUT || true) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
}
if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
mDockLeft, mDockTop, mDockRight, mDockBottom));
// decide where the status bar goes ahead of time
if (mStatusBar != null) {
// apply any navigation bar insets
pf.left = df.left = mUnrestrictedScreenLeft;
pf.top = df.top = mUnrestrictedScreenTop;
pf.right = df.right = mUnrestrictedScreenWidth - mUnrestrictedScreenLeft;
pf.bottom = df.bottom = mUnrestrictedScreenHeight - mUnrestrictedScreenTop;
vf.left = mStableLeft;
vf.top = mStableTop;
vf.right = mStableRight;
vf.bottom = mStableBottom;
mStatusBarLayer = mStatusBar.getSurfaceLayer();
// Let the status bar determine its size.
mStatusBar.computeFrameLw(pf, df, vf, vf);
// For layout, the status bar is always at the top with our fixed height.
mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
// If the status bar is hidden, we don't want to cause
// windows behind it to scroll.
if (mStatusBar.isVisibleLw()) {
// Status bar may go away, so the screen area it occupies
// is available to apps but just covering them when the
// status bar is visible.
mDockTop = mUnrestrictedScreenTop + mStatusBarHeight;
mContentTop = mCurTop = mDockTop;
mContentBottom = mCurBottom = mDockBottom;
mContentLeft = mCurLeft = mDockLeft;
mContentRight = mCurRight = mDockRight;
if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
String.format(
"dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
mDockLeft, mDockTop, mDockRight, mDockBottom,
mContentLeft, mContentTop, mContentRight, mContentBottom,
mCurLeft, mCurTop, mCurRight, mCurBottom));
}
if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw()) {
// If the status bar is currently requested to be visible,
// and not in the process of animating on or off, then
// we can tell the app that it is covered by it.
mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
}
}
}
}
修改:
修改默认值.
public void setInitialDisplaySize(Display display, int width, int height, int density) {
mDisplay = display;
int shortSize, longSize;
if (width > height) {
shortSize = height;
longSize = width;
mLandscapeRotation = Surface.ROTATION_0;
mSeascapeRotation = Surface.ROTATION_180;
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_reverseDefaultRotation)) {
mPortraitRotation = Surface.ROTATION_90;
mUpsideDownRotation = Surface.ROTATION_270;
} else {
mPortraitRotation = Surface.ROTATION_270;
mUpsideDownRotation = Surface.ROTATION_90;
}
} else {
shortSize = width;
longSize = height;
mPortraitRotation = Surface.ROTATION_0;
mUpsideDownRotation = Surface.ROTATION_180;
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_reverseDefaultRotation)) {
mLandscapeRotation = Surface.ROTATION_270;
mSeascapeRotation = Surface.ROTATION_90;
} else {
mLandscapeRotation = Surface.ROTATION_90;
mSeascapeRotation = Surface.ROTATION_270;
}
}
mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height);
// Height of the navigation bar when presented horizontally at bottom
mNavigationBarHeightForRotation[mPortraitRotation] =
mNavigationBarHeightForRotation[mUpsideDownRotation] =
mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height);
mNavigationBarHeightForRotation[mLandscapeRotation] =
mNavigationBarHeightForRotation[mSeascapeRotation] =
mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape);
// Width of the navigation bar when presented vertically along one side
mNavigationBarWidthForRotation[mPortraitRotation] =
mNavigationBarWidthForRotation[mUpsideDownRotation] =
mNavigationBarWidthForRotation[mLandscapeRotation] =
mNavigationBarWidthForRotation[mSeascapeRotation] =
mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width);
// SystemUI (status bar) layout policy
int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
if (shortSizeDp < 600) {
// 0-599dp: "phone" UI with a separate status & navigation bar
mHasSystemNavBar = false;
mNavigationBarCanMove = false;//原来的值为true
} else if (shortSizeDp < 720) {
// 600+dp: "phone" UI with modifications for larger screens
mHasSystemNavBar = false;
mNavigationBarCanMove = false;
}