Как сделать полноэкранный режим без системных баров для показа заставки?

Я пытаюсь сделать полноэкранный режим без системных панелей в качестве экрана-заставки, но у меня есть некоторые проблемы с изменением размера моего корневого макета при запуске моего приложения.

У меня нет проблем с нижней частью, потому что мой корневой макет изменяет размер за панелью навигации и перемещается в конец экрана, что я действительно хотел сделать. Проблема заключается в верхней части корневого макета, потому что она не идет в верхнюю часть экрана. В верхней части экрана у меня есть черное пустое пространство, которое остается после того, как я скрою строку состояния.

ПРИМЕЧАНИЕ. Я использую minSdkVersion 22 и targetSdkVersion 29.

В демонстрационных целях я буду использовать простой код с одним действием и одним соответствующим XML-файлом макета с зеленым фоном и двумя кнопками в макете ограничений в качестве корневого макета.

Основная деятельность:

package com.systemwindowexercise

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        window.navigationBarColor = resources.getColor(R.color.translucent)
        window.statusBarColor = resources.getColor(R.color.translucent)

        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_FULLSCREEN)

    }

}

Activity_main:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/constraint_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_green_light"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

темы:

<style name="Theme.SystemWindowExercise" parent="Theme.MaterialComponents.DayNight.NoActionBar">

Слева — приложение до того, как я коснулся экрана с черным пространством без системных полос, но с неправильным изменением размера корневого макета (зеленый цвет), а справа — приложение после того, как я коснулся экрана с системными полосами и правильным измененным корневым макетом.

введите здесь описание изображения

Я хочу приложение с полным экраном без черного пространства и с полностью измененным корневым макетом и скрытыми системными панелями для моего экрана-заставки, прежде чем я буду взаимодействовать с экраном. Как я могу это сделать?

ОБНОВЛЕНИЕ: я использую minSdkVersion 22 и targetSdkVersion 29 и тестировал на Samsung Galaxy A40 (Android 10, API 29). На Samsung я всегда получаю черное пространство сверху, но на ZTE Nubia (API 22) все работает нормально. Единственным решением на данный момент является изменение настроек устройства следующим образом: Как включить полноэкранные приложения на Galaxy, что @SlothCoding показал мне в комментарии.


person Dezo    schedule 03.01.2021    source источник
comment
Проверьте этот вопрос: stackoverflow.com/questions/56353716/   -  person SlothCoding    schedule 04.01.2021
comment
Я тестировал на реальном устройстве с API 29, и кажется, что это приложение работает в полноэкранном режиме, только если я переключаюсь на полноэкранное приложение в настройках устройства. Я также тестировал API 22, и приложение работало в полноэкранном режиме с моим кодом без изменения настроек устройства.   -  person Dezo    schedule 04.01.2021
comment
Мне интересно, есть ли код, чтобы исправить это, не возясь с настройками устройства?   -  person Dezo    schedule 04.01.2021
comment
Проверьте это для документации: developer.android.com/training/system-ui/immersive ... Также проверьте этот ответ, возможно, это может сделать это:   -  person SlothCoding    schedule 04.01.2021


Ответы (2)


Чтобы скрыть строку состояния, панель навигации в вашем приложении и не показывать, когда пользователь взаимодействует с экраном:
Сначала перейдите к своему разрешению/теме (измените его также в ночном режиме):

<style name="Theme.xxx" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">@android:color/transparent</item>
        <!-- Customize your theme here. -->
        <item name="android:windowTranslucentStatus">false</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds" tools:targetApi="lollipop">true</item>
</style>

Затем перейдите к своему первому действию запуска экрана (у меня это основное действие), создайте эту функцию:

@SuppressLint("RestrictedApi")
fun createFullScreen(context: Context) {
        val window = getActivity(context)?.window
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            window?.apply {
                setDecorFitsSystemWindows(false)
            }
        } else {
            window?.apply {
                setFlags(
                    WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN
                )
                decorView.apply {
                    systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
                            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
                            View.SYSTEM_UI_FLAG_FULLSCREEN or 
                            
                }
                statusBarColor =
                    ContextCompat.getColor(context, android.R.color.transparent)
            }
        }
    }

Если вы хотите сделать полноэкранный режим на устройстве Android выше, чем API 30 (Android R), просто сделайте это и выполните тот же шаг:

@SuppressLint("RestrictedApi")
fun createFullScreen(context: Context) {
        val window = getActivity(context)?.window

        window?.apply {
            setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
            )
            decorView.apply {
                systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
                        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
                        View.SYSTEM_UI_FLAG_FULLSCREEN or
                        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            }
            statusBarColor =
                ContextCompat.getColor(context, android.R.color.transparent)
        }
    }

И, наконец, просто поместите его в функцию onCreate() следующим образом:

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var adapterViewPager: PosterViewPagerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
//      Here for your called function
        createFullScreen(this@MainActivity)
}
person Nguyễn Hoàng Ân    schedule 04.01.2021
comment
Я обновил свою Android-студию до API 30, и ваш код не работал на устройстве с API 29, но работал на устройстве с API 22. Это означает, что на моем Samsung A40 с API 29 у меня все еще есть черное пространство вверху. - person Dezo; 04.01.2021
comment
@Dezo Я обновил код, вам просто нужно удалить мой if-else, чтобы проверить API в функции createFullScreen(). - person Nguyễn Hoàng Ân; 04.01.2021
comment
Тем не менее получить черное пространство на вершине. Возможно, это проблема с телефонами Samsung Galaxy Axx. - person Dezo; 04.01.2021

<style name="Theme.xxx" parent="Theme.MaterialComponents.DayNight.NoActionBar">    //no actionbar, but status bar exists
    <item name="android:windowFullscreen">true</item>                       //remove status bar

Результат:

введите здесь описание изображения

person Sam Chen    schedule 03.01.2021
comment
Это не сработало на устройстве с API 29, у меня все равно появляется черное пространство сверху. - person Dezo; 04.01.2021
comment
@Dezo Проверьте мое обновленное изображение, оно отлично работает для меня (Android 10). Попробуйте закомментировать свой логический код и запустить его снова. - person Sam Chen; 04.01.2021
comment
Я попробовал еще раз и не работал на Samsung Galaxy A40 (Android 10), потому что у меня все еще появляется черное пространство сверху. На данный момент, я думаю, работает только это: gottabemobile.com/how-to-enable-full-screen-apps-on-galaxy-s10 Возможно, это работает на других телефонах, но не на Samsung Galaxy A40. - person Dezo; 04.01.2021