アプリによって、ゲームやギャラリーなどは全画面での表示が好まれるケースがあります。ステータスバーやナビゲーションバーが消えてくれると見やすいというような時にどのようにするといいのでしょうか、
2021.2.1
Fullscreen
例えばこのような通常の表示で、
- Status bar
- Title bar
- Navigation bar
- (System bar = Status bar + Navigation bar)
を非表示にしたい場合
Status bar とNavigation bar については API 30 以降はそれ以前と異なっています。
- systemUiVisibility: API 29 まで
- WindowInsetsController: API 30 以降
Title barについてはThemeの変更などで対応できます。
API29まではこちらを参考にしてください、ちなみにAndroid Studio 4.1.3 のフルスクリーンのテンプレートでも古い方法でした(2021年4月)
Title bar
最初にTtile barを非表示にしたいと思います。
NoActionBar のThemeに設定変更します。
Themeの変更は、res/values/themes/ 以下にあります。
デフォルトではこのようになっているparentをNoActionBarに変更
1 |
parent="Theme.MaterialComponents.DayNight.DarkActionBar" |
例えばこのようにタイトルバーを非表示にできます。
1 |
parent="Theme.MaterialComponents.DayNight.NoActionBar |
画像は “centerCrop” を設定しているためにタイトルバーが無くなった分だけ拡大されました。
このケースでの設定です。
theme.xml
1 2 3 4 5 6 |
<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <style name="Theme.TestNoTitlebar" parent="Theme.MaterialComponents.DayNight.NoActionBar"> ... </style> </resources> |
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:src="@drawable/img2" android:contentDescription="@string/my_image_description" android:scaleType="centerCrop" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="app_name">Your App Name</string> <string name="my_image_description">kimono</string> </resources> |
NoActionBarとなるThemeは他にもあります。
1 2 3 4 5 6 7 |
Theme.MaterialComponents.NoActionBar Theme.MaterialComponents.DayNight.NoActionBar Theme.MaterialComponents.Light.NoActionBar Theme.AppCompat.NoActionBar Theme.AppCompat.DayNight.NoActionBar Theme.AppCompat.Light.NoActionBar |
あるいは、ActionBarはAppCompatActivity()によって実現しているので単純に
Activity()にすれば表示されなくなります。
hide & show bars
WindowInsetsController を使います。WindowInsetsController | Android Developers
status bar と navigation bar を非表示にするために
hide(types: Int)
を使います。
1 2 3 4 |
getWindow().getDecorView().getWindowInsetsController().hide( android.view.WindowInsets.Type.statusBars() | android.view.WindowInsets.Type.navigationBars() ); |
両方のbarを非表示にしますが、片方だけでも可能です
1 2 3 |
getWindow().getDecorView().getWindowInsetsController().hide( android.view.WindowInsets.Type.statusBars() ); |
表示させる場合は、show(types: Int) を使います
1 2 3 4 |
getWindow().getDecorView().getWindowInsetsController().show( android.view.WindowInsets.Type.statusBars() | android.view.WindowInsets.Type.navigationBars() ); |
とします。
また、System barはStatus bar と Navigation barの両方をさすのでまとめて以下のようにもできます。
1 2 3 |
getWindow().getDecorView().getWindowInsetsController().show( android.view.WindowInsets.Type.systemBars() ); |
behavior
以前の全画面の方法として Immersive Sticky モードがありました。アプリ優先型没入モードというような意味です。
通常は全画面で何か必要な場合のみbarを表示させて、数秒後には元の全画面に戻るモードです
1 2 |
getWindow().getInsetsController().setSystemBarsBehavior( WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); |
これは半透明なバーですが透明ではないバーを表示させたり
BEHAVIOR_SHOW_BARS_BY_SWIPE
スワイプではなくタッチで表示させる
BEHAVIOR_SHOW_BARS_BY_TOUCH
などがあります。
サンプルコード
ボタンを使って、バーの非表示から半透明でスワイプで一時表示
非表示から表示させるコードを作ってみます。
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//package com.example.xxx import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.WindowInsetsController; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = findViewById(R.id.button1); button1.setOnClickListener( v -> { getWindow().getDecorView().getWindowInsetsController().show( // android.view.WindowInsets.Type.statusBars() // | android.view.WindowInsets.Type.navigationBars() android.view.WindowInsets.Type.systemBars() ); }); Button button2 = findViewById(R.id.button2); button2.setOnClickListener( v -> { getWindow().getDecorView().getWindowInsetsController().hide( // android.view.WindowInsets.Type.statusBars() // | android.view.WindowInsets.Type.navigationBars() android.view.WindowInsets.Type.systemBars() ); getWindow().getInsetsController().setSystemBarsBehavior( WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); }); } } |
レイアウトです
何か画像があるとわかりやすいです
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:src="@drawable/img2" android:contentDescription="@string/my_image_description" android:scaleType="centerCrop" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button1" android:layout_width="100dp" android:layout_height="wrap_content" android:text="@string/button1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.9" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.125" /> <Button android:id="@+id/button2" android:layout_width="100dp" android:layout_height="wrap_content" android:text="@string/button2" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.9" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.2" /> </androidx.constraintlayout.widget.ConstraintLayout> |
リソース
strings.xml
1 2 3 4 5 6 |
<resources> <string name="app_name">Your App Name</string> <string name="my_image_description">kimono</string> <string name="button1">appear</string> <string name="button2">hide</string> </resources> |
Title barを非表示にするためThemeを変更します。
theme.xml
1 2 3 4 5 6 |
<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <style name="Theme.TestWindowInsetsController" parent="Theme.MaterialComponents.DayNight.NoActionBar"> ... </style> </resources> |
これで実行してみましょう
これはAPI30からなのでそれ以前ではsystemUiVisibilityを使わないといけないのでAPIによる切り分けが必要になります。
Reference:
WindowInsetsController | Android Developers