安卓 L 版本中,应用程序的内容位于导航栏后面。

37

enter image description here

如您所见,我的“Got It”按钮在导航栏后面,我无法修复它!!! 我已经尝试过

<item name="android:fitsSystemWindows">true</item>  

除了在布局文件中设置它之外。

我的主题在value-21中是:

 <style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowActionBar">false</item>
        <item name="android:windowFullscreen">false</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:fitsSystemWindows">true</item>
    </style>

应用程序中所有屏幕都是相同的情况。

请帮忙。


1
尝试:View.bringToFront(); - user863873
1
@user863873:布局不应使用此空间。它应该在这些按钮上方。 - nitesh goel
你能否把“Got it”按钮放在导航栏前面?我似乎无法实现它。你能帮我吗?你还添加了哪些标志到窗口中?我添加了你所有的标志,但导航栏总是在我的活动前面。 - user3632055
@niteshgoel,你能回答一下吗? - user3632055
是的,它就是这样工作的。请检查我的答案,看我是如何解决它的。 - nitesh goel
9个回答

46

这是解决方案。

大多数布局可以通过在values-v21 style.xml中添加这些属性来解决。

<item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:fitsSystemWindows">true</item>

对于其他人,我已经计算了导航栏的高度并在我的视图中添加了边距。

public static int getSoftButtonsBarSizePort(Activity activity) {
    // getRealMetrics is only available with API 17 and +
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        DisplayMetrics metrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int usableHeight = metrics.heightPixels;
        activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
        int realHeight = metrics.heightPixels;
        if (realHeight > usableHeight)
            return realHeight - usableHeight;
        else
            return 0;
    }
    return 0;
}

注意: 使用上述解决方案可以使一切正常,但我在我的应用程序中还使用了PopupWindow。在Android L中,PopupWindow的布局会混乱。查看问题和解决方案在这里


10
我将以下内容添加到我的样式中: <item name="android:windowTranslucentNavigation">true</item> <item name="android:fitsSystemWindows">true</item>它奏效了!没有任何内容被绘制在导航栏的后面。但现在我的导航栏是深灰色而不是黑色。将TranslucentNavigation设置为false可以使栏变为黑色,但是内容会绘制在其后面。你能解释一下为什么这些属性起作用以及如何保持导航栏为黑色吗? - klong15
您已经定义了该方法,但是您没有告诉我们如何使用它或调用它。请问您能否告诉我们从哪里调用该方法以及如何使用它所返回的内容? - Neri
这很有帮助,但如何判断用户何时打开或关闭软导航键栏?以便我们可以调整填充大小? - Morteza Rastgoo

7

非常简单,只需将以下代码添加到你的父布局xml文件中:

android:fitsSystemWindows="true"

5
不支持派可能是因为它不支持 Android M 以后的版本。 - Ajay Pandya
对我有用,在运行 Android Pie 的 Android 模拟器中进行了测试。 - Lins Louis

6

为了获得更好的用户体验,您不应该使用 android:windowTranslucentNavigation 来阻止导航键区域。

相反,如果您正在使用 ResideMenu 库,则可以在 ResideMenu.java 中添加此方法作为更好的解决方案:

  @Override
protected boolean fitSystemWindows(Rect insets) {
    int bottomPadding = insets.bottom;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Resources resources = getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            bottomPadding += resources.getDimensionPixelSize(resourceId);
        }
    }
    this.setPadding(viewActivity.getPaddingLeft() + insets.left, viewActivity.getPaddingTop() + insets.top,
            viewActivity.getPaddingRight() + insets.right, viewActivity.getPaddingBottom() + bottomPadding);
    insets.left = insets.top = insets.right = insets.bottom = 0;
    return true;
}

如果您正在使用SlidingMenu库,则可以通过以下方法将mod更改为SLIDING_CONTENT

menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);

希望这能节省您的时间。


+1 我因为ResideMenu遇到了同样的问题,浪费了很多时间,但这个答案帮助了我。谢谢! - WonderSoftwares
我也在使用Reside菜单。如何为Android P导航手势功能做准备?当导航栏被隐藏时,我仍然得到导航栏的高度而不是零。你能帮我吗? - Nik

4

只需在设置内容视图时,在Activity的onCreate()中设置以下内容:

int mScreenWidth = getWindowManager().getDefaultDisplay().getWidth();
int mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
View view = getLayoutInflater().inflate(R.layout.activity_main, null);
setContentView(view, new ViewGroup.LayoutParams(mScreenWidth, mScreenHeight));

3

Activity 的 onCreate 方法中使用此代码(如果你有 BaseActivity,你可以在那里做这个操作,以使所有活动都适用于此):

ViewCompat.setOnApplyWindowInsetsListener(
            findViewById(android.R.id.content), (v, insets) -> {
                ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
                params.bottomMargin = insets.getSystemWindowInsetBottom();
                return insets.consumeSystemWindowInsets();
            });

当一个布局有这个标记时,意味着它要求系统应用窗口插图。在我们的情况下,这意味着FrameLayout希望应用与状态栏高度相等的填充。


1
对于lambda之前的代码: `.setOnApplyWindowInsetsListener (findViewById(android.R.id.content), new OnApplyWindowInsetsListener() { @Override public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {// .. } } );` - Gene Bo

1

我尝试了很多上面的答案,但都没有对我起作用。我将我的相对布局(其中我的按钮必须附加到底部)包裹在另一个线性布局中。这对我来说是神奇的。

如果有人能够添加原因,那会更有帮助。


1
在大多数情况下,默认情况下,导航栏应该始终在应用程序下方,除非您触发了某个设置。
如果这是您想要的行为,请确保不运行此行代码:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

在一些手机上,这是导致问题的原因。 - Rohaitas Tanoli

0

popupWindowsoftInputMode设置为SOFT_INPUT_ADJUST_RESIZE可以解决这个问题。


0
在设置Java的setContentView之前尝试这个,我的问题就是通过这个得到解决的。
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接