【问题标题】:How to set fullscreen in Android R?如何在 Android R 中设置全屏?
【发布时间】:2020-10-31 05:46:18
【问题描述】:

我需要在我的应用中全屏显示屏幕。为此,我正在使用此代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requestWindowFeature(Window.FEATURE_NO_TITLE)
    window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN)
    setContentView(R.layout.activity_camera_photo)

但是,WindowManager.LayoutParams.FLAG_FULLSCREEN 标志已弃用。

我的应用支持 Android Lollipop (API 21) 到 Android R (API 30)。 使屏幕变为全屏的正确方法是什么?

【问题讨论】:

    标签: android android-layout fullscreen android-5.0-lollipop android-11


    【解决方案1】:

    科特林

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.layout_container)
        @Suppress("DEPRECATION")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            window.insetsController?.hide(WindowInsets.Type.statusBars())
        } else {
            window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
            )
        }
    }
    

    如果这没有帮助,请尝试在布局文件中删除 android:fitsSystemWindows="true"

    JAVA

    class Activity extends AppCompatActivity {
    
    @Override
    @SuppressWarnings("DEPRECATION")
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_container);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            final WindowInsetsController insetsController = getWindow().getInsetsController();
            if (insetsController != null) {
                insetsController.hide(WindowInsets.Type.statusBars());
            }
        } else {
            getWindow().setFlags(
                    WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN
            );
        }
    }
    }
    

    【讨论】:

    • 这里的window对象是什么类型,在Java中应该如何初始化呢? @Andriy D.
    • java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.WindowInsetsController com.android.internal.policy.DecorView.getWindowInsetsController()' on a null object reference
    • @AndriyD。我的活动就像您在答案上写的一样。我添加了 getWindow().getInsetsController();在 setContentView(R.layout.main_layout) 之前;但是当我在 setContentView 之后调用 getWindow() 工作正常并且不返回 null 时。我想我们必须调用 getWindow().getInsetsController();在 setContentView() 之后。
    • 你不能在onCreate 中使用它,它应该在onAttachedToWindow 中。检查public @Nullable WindowInsetsController getWindowInsetsController() { if (mAttachInfo != null) { return mAttachInfo.mViewRootImpl.getInsetsController(); }
    • 使用兼容版本的WindowInsets.Type摆脱api检查
    【解决方案2】:

    我遇到了类似 user924 的问题

    java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.WindowInsetsController com.android.internal.policy.DecorView.getWindowInsetsController()' on a null object reference

    我可以通过在之后 setContentView 添加全屏设置代码来解决这个问题。此外,通常情况下,全屏屏幕不仅没有状态栏,也没有导航栏。此外,仅hide() 方法是不够的。如果我们只放这一行,当我们向下滑动屏幕看到状态栏时,它会下降,但不会再上升。通过设置systemBarBehavior,我们可以让状态栏和导航栏只在我们熟悉的全屏滑动时临时出现。

    setContentView(R.layout.YOUR_LAYOUT)
    
    //Set full screen after setting layout content
    @Suppress("DEPRECATION")
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        val controller = window.insetsController
    
        if(controller != null) {
            controller.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
            controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        }
    } else {
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
    }
    

    【讨论】:

      【解决方案3】:

      对于 API >= 30,使用 WindowInsetsController.hide():

      window.insetsController.hide(WindowInsets.Type.statusBars())
      

      【讨论】:

      • 此解决方案需要版本 sdk 上的条件
      • 这里的window对象是什么类型,在Java中应该如何初始化?@Mimouni @Saurabh Thorat
      • @RAWNAKYAZDANI 对于 Java,请在您的活动中使用 getWindow()
      • @SaurabhThorat hide() 是非静态方法,我不能使用静态 onCreate 方法。如何解决?
      • java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.WindowInsetsController com.android.internal.policy.DecorView.getWindowInsetsController()' on a null object reference
      【解决方案4】:

      代码可在搭载 Android 4.0 (API 14) 至 10 (API 29) 的真实手机和搭载 Android R (API 30) 的 SDK 手机模拟器上运行。

      在样式资源中编写启动活动的主题。

       <!--Splash screen theme-->
        <style name="SplashTheme" parent="@style/Theme.AppCompat.NoActionBar">
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowBackground">@color/colorSplashBackground</item>
        </style>
      

      够了。无需代码为启动活动隐藏栏。

      主要活动。

      使用主题。

      <!-- Base application theme. -->
          <style name="myAppTheme" parent="@style/Theme.AppCompat.NoActionBar">
          <!-- Customize your theme here. -->
          </style>
      

      在 MainActivity 类中编写代码。

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate( savedInstanceState );
          // Hide bar when you want. For example hide bar in landscape only
          if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
              hideStatusBar_AllVersions();
          }
          setContentView( R.layout.activity_main );
          // Add your code
          }
      

      实现方法。

      @SuppressWarnings("deprecation")
      void hideStatusBar_Deprecated() {
          if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {  // < 16
              getWindow().setFlags(
                      WindowManager.LayoutParams.FLAG_FULLSCREEN,
                      WindowManager.LayoutParams.FLAG_FULLSCREEN);
          } else {  // 16...29
              View decorView = getWindow().getDecorView();
              decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
      
              ActionBar ab = getSupportActionBar();
              if (ab != null) { ab.hide(); }
      
              getWindow().setFlags(
                      WindowManager.LayoutParams.FLAG_FULLSCREEN,
                      WindowManager.LayoutParams.FLAG_FULLSCREEN);
          }
      }
      
      @TargetApi(Build.VERSION_CODES.R) // >= 30
      void hideStatusBar_Actual() {
          View decorView = getWindow().getDecorView();
          decorView.getWindowInsetsController().hide(WindowInsets.Type.statusBars());
      }
      
      void hideStatusBar_AllVersions(){
          if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
              hideStatusBar_Deprecated();
          } else {
              hideStatusBar_Actual();
          }
      }
      

      【讨论】:

        【解决方案5】:
        fullScreenButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        
                            WindowInsetsController controller = getWindow().getInsetsController();
                            //BEFORE TOGGLE
        //                    System.out.println(controller.getSystemBarsAppearance());
        //                    System.out.println(controller.getSystemBarsBehavior());
                            if(controller != null) {
                                if (controller.getSystemBarsBehavior() == 0) {
                                    controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
                                    controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
                                } else {
                                    controller.show(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
                                    controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH);
                                }
                            }
                        } else {
                            WindowManager.LayoutParams attrs = getWindow().getAttributes();
                            attrs.flags ^= WindowManager.LayoutParams.FLAG_FULLSCREEN;
                            getWindow().setAttributes(attrs);
                        }
                        //AFTER TOGGLE
                        //                    System.out.println(controller.getSystemBarsAppearance());
        //                    System.out.println(controller.getSystemBarsBehavior());
                    }
                });
        

        【讨论】:

          【解决方案6】:
             override fun onAttachedToWindow() {
              super.onAttachedToWindow()
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                  val controller = window.insetsController
                  if (controller != null) {
                      controller.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
                      controller.systemBarsBehavior =
                          WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
                  }
              }
          }
          
          @Suppress("DEPRECATION")
          private fun makeFullScreen() {
              // Remove Title
              requestWindowFeature(Window.FEATURE_NO_TITLE)
              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
                  window.setFlags(
                      WindowManager.LayoutParams.FLAG_FULLSCREEN,
                      WindowManager.LayoutParams.FLAG_FULLSCREEN
                  )
              }
              // Hide the toolbar
              supportActionBar?.hide()
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-02-11
            • 1970-01-01
            • 2015-01-31
            • 2011-08-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多