React Native で全画面表示にする方法

例によって React Native 修行中である。Expo SDK を使って開発して、Expo Go でシミュレータを動かして、EAS でリモートビルドして、たいへん便利である。

ただ全画面(フルスクリーン)表示に問題があったので調べて解決したメモ。

困ったこと

React Native + Expo + EAS で Android アプリの開発をしているとき全画面表示が上手くいかない。Expo SDK のバージョンは 46.0.9。

具体的には、ナビゲーションバーやステータスバーを非表示とするため Expo のドキュメント にしたがって app.jsonandroidNavigationBar.visible 属性を immersive としていた。expo-navigation-bar をインストールしたうえで以下のように設定する感じである。

{
  "androidNavigationBar": {
    "visible": "immersive"
  }
}

これで Expo Go によるシミュレータではちゃんと全画面表示になる。しかし、EAS でビルドして実機の Android 端末で動かすと全画面表示にならないのである。ビルド時に特にそれらしいエラーが出ていないし解決策が分からない。困った。

解決策

かなり真面目にググったところ以下のようなページがあり、結論から言うと、このページに記載されている方法で EAS ビルドしても全画面表示が保たれるようになった。

fyi/android-navigation-bar-visible-deprecated.md at master · expo/fyi · GitHub

どうやら、Expo の app.json に記述する androidNavigationBar.visible 属性は、ビルドすると Android SDKView.setSystemUiVisibility に変換されるようである。そして、この APIAndroid API level 30 から deprecated になっている。API ドキュメント にもそう書いてある。これが原因で、今回のビルド後に全画面表示されない問題が引き起こされているっぽい(定かではないが)。

これを回避する方法として、以下の手順を実施すれば全画面表示を実現できる。

手順1. ライブラリのインストール

まず expo-navigation-bar と expo-status-bar をプロジェクトの依存関係に追加する。expo install とか叩けばオッケー。

手順2. ライブラリの呼び出し

そして、ナビゲーションバーとステータスバーを非表示にするため、プログラム内で以下を呼び出す。自分は常に全画面表示にしたかったので App.js 内で呼び出すようにした。

import * as NavigationBar from "expo-navigation-bar";
import { setStatusBarHidden } from "expo-status-bar";

NavigationBar.setPositionAsync("relative");
NavigationBar.setVisibilityAsync("hidden");
NavigationBar.setBehaviorAsync("inset-swipe");
setStatusBarHidden(true, "none");

手順3. app.json の編集

さきほど記載した androidNavigationBar.visible の部分を以下に置き換える。

{
  "androidStatusBar": {
    "hidden": true
  },
  "plugins": [
    [
      "expo-navigation-bar",
      {
        "position": "relative",
        "visibility": "hidden",
        "behavior": "inset-swipe"
      }
    ]
  ]
}

こうすれば EAS ビルドしても全画面表示になる。めでたし。