Android R 隐藏状态栏 -> 移动视图向下,出现黑色矩形

12

Android R + Pixel 4 模拟器: 当我隐藏状态栏时,主视图会向下移动,顶部出现一个黑色的正方形(与状态栏大小相同)。 在 Android 11 之前它是可以工作的。 看起来很简单,但我找不到解决方法……而且我需要全屏模式。

我尝试使用 SYSTEM_UI_FLAG_FULLSCREEN(现在已被弃用)和 controller.hide(WindowInsets.Type.statusBars()); 两种方法都存在同样的问题。

enter image description here

这是主要代码: MainActivity.java

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    Button buttonShow = findViewById(R.id.b1);
    buttonShow.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
           showBars();
        }
    });

    Button buttonHide = findViewById(R.id.b2);
    buttonHide.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
          hideBars();
        }
    });

    showBars();
}

public void showBars(){

    View decorView = getWindow().getDecorView();
    int uiOptions =  View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;

    decorView.setSystemUiVisibility(uiOptions);

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    // New code For Android 11, same effect...
    /*
    WindowInsetsController controller = getWindow().getInsetsController();
    if(controller != null) {
        controller.show(WindowInsets.Type.navigationBars());
        controller.show(WindowInsets.Type.statusBars());
        controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
    }*/
}

public void hideBars(){


    View decorView = getWindow().getDecorView();
    int uiOptions = 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
            | View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_IMMERSIVE;


    decorView.setSystemUiVisibility(uiOptions);

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    // New code For Android 11, same effect...
    /* WindowInsetsController controller = getWindow().getInsetsController();
      if(controller != null) {
          controller.hide(WindowInsets.Type.navigationBars());
          controller.hide(WindowInsets.Type.statusBars());
          controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
      }*/

}

activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="@color/purple_200"
    android:id="@+id/layoutMain">


    <Button
        android:id="@+id/b1"
        android:layout_marginTop="200dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="show" />

    <Button
        android:id="@+id/b2"
        android:layout_marginTop="100dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hide"
/>

</RelativeLayout>

你需要应用以下代码才能使活动全屏,同时状态栏位于其顶部: https://dev59.com/iFcP5IYBdhLWcg3w_u4U - axar
3个回答

4

这是我的解决方案:
为您希望全屏并且没有切口的活动创建一个使用v27配置的样式资源文件:

<style name="Theme.MyApp.ActivityFullscreenNoCutout">
    <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>

在清单文件中为您的活动分配样式:

<activity android:name=".MyActivity"
        android:theme="@style/Theme.MyApp.ActivityFullscreenNoCutout"/>

链接:https://developer.android.com/guide/topics/display-cutout

如果您有一个操作/应用程序栏,您必须将工具栏添加到您的活动中,而不使用默认工具栏。

链接:https://developer.android.com/training/appbar/setting-up


3
非常感谢。我直接将其放入主题中,也可以正常工作:<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> - arun
谢谢Arun!这是对我有效的方法:<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item> - Sabri Meviş
对我来说,它也直接在主题中起作用,就像@arun一样 - 但是你如何设置v27配置呢?是将minSdkVersion增加到27吗?这是必需的吗?我希望能够以24+为目标。 - Noitidart
这并不是必需的,也不会增加minSdkVersion。创建一个单独的资源文件可以让你在不同的配置之间分离代码。对于api 26及以下版本,主题文件中的配置将被忽略。 - Olivier M

1
在活动代码的某个地方...
    @TargetApi(Build.VERSION_CODES.R) 
void hideStatusBar_with_API30() {
    View decorView = getWindow().getDecorView();
    // Order swiped status bar to appear semitransparent.
    // If you do not that
    //  then once appeared bar will not disappear after nor few seconds nor you gesture.
    decorView.getWindowInsetsController().setSystemBarsBehavior(
            WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
    // Hide the status bar.
    decorView.getWindowInsetsController().hide(WindowInsets.Type.statusBars());
    // The status bar is allowed to appear with a swipe gesture.
    // When it is then app layout is resized.
    // To prevent changing the layout, you need to add:
    getWindow().setDecorFitsSystemWindows(false);
    // The status bar will appear over stable layout
}

1
尝试这个代码片段。
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
    }

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