最近React Nativeに触り始め、OSごとに異なる画面やコンポーネントのheight/widthの挙動にやや苦しんだので、調べたことをまとめました。
バージョン
React Native v0.58
前提
これから解説で使用する単語の定義は以下の通りです。
Window height / Window width
React Native標準のDimensions
を使用し、以下のようなコードで取得できる値を指します。
import {Dimensions} from 'react-native';
Dimensions.get('window').width; // Window width
Dimensions.get('window').height; // Window height
Screen height / Screen width
React Native標準のDimensions
を使用し、以下のようなコードで取得できる値を指します。
import {Dimensions} from 'react-native';
Dimensions.get('screen').width; // Screen width
Dimensions.get('screen').height; // Screen height
また、キーボード周りの挙動は、Androidの場合、AndroidManifest.xmlの設定値によって変化します。今回は設定を変更していないことを前提としています。詳しくは私のブログにあるので、興味があればご覧ください。
【ReactNative】AndroidとiOSではキーボードが開いた時の挙動が違う - ゆるふわ技術日誌
iOS
iOSの仕様は割と単純です。
width/height共に、ScreenとWindowは同じ値を指します。
また、StatusBar.currentHeight
を使用しても、StatusBarの高さを取得することはできません。
x = 0, y = 0の位置も画像上のOriginと書かれている位置になるので、適宜StatusBarを避ける処理をしてあげる必要があります。
そして、図のピンクで塗ってある領域は、style
porpsに{flex: 1}
を渡した場合のコンポーネントの領域を表しています。こちらもキーボードが展開しても変わらないため、キーボードに隠れないように、コンポーネントを配置したい場合には、そのようなライブラリを使うなり、自分でイベントハンドラを設定してやって、うまいことやってあげる必要があります。
Android
曲者なのがAndroidです。
(SketchにAndroid用のパーツがなかったので図がお粗末ですが、なんとなく察してください。下の黒い領域はホームボタンや戻るボタンが出ている、あの領域です。察してください)
こちらはiOSとは異なり、WindowとScreenのheightが別の値を指します。
端的にまとめると、
- Screen heightは、物理的な画面の高さ
- Window heightは、ホームボタンのある領域を除いた画面の高さ
を返します。
そして、Androidでは、StatusBar.currentHeight
が値を返します。また、この値は、StatusBarを非表示にしている場合でも返ります。
また、StatusBarが表示されている場合、x = 0, y = 0の位置は、画像上のOriginの位置になります。(非表示の場合は、物理的な画面の一番左上になります)
そのため、特にStatusBarを避けるような処理を自分で書く必要はありません。
最後に、{flex: 1}
を指定した際の領域(画像上ピンクの塗りつぶし)ですが、Androidはキーボードを避けるように領域が縮みます。
そのため、キーボードを避ける処理を書く必要はありませんが、領域の大きさが変わっても表示が崩れないようなstyleを書いてあげる必要があると言えます。
(繰り返しになりますが、この挙動はAndroidManifest.xmlの設定によって変えることができます。詳しくは、前提セクションにあるブログ記事をご覧ください。)