「画面サイズに合わせて画像や図形を調整したい」
HTMLではFlexBoxを使うことで、画像や図形、領域をアイテム数に合わせて適当なサイズに自動調整することができます。
React Nativeでも同様にFlexBoxを指定することができます。
今回は、本家React Nativeのドキュメントとサンプルコードを参考にしながら、FlexBoxを紹介していきます。
また実装の紹介にはExpoを利用しています。
-
【React Native】Expoを利用して簡単にアプリ共有
2022/4/9 app, expo, javascript, programming, react, react-native, share, プログラミング
ロナえるも夫です。 「自分のコードの実行結果をブログに表示したい」 という人のためにCodeSandboxを紹介しました。 「CodeSandboxで簡単に自分のコードを紹介できます!」といいましたが ...
FlexBoxとは?
FlexBoxとは、画面に表示するアイテム数に応じて、各々のサイズや間隔を自動で調整できる機能です。
実際にはFlexBoxを使わずとも、他のstyleパラメータを組み合わせて同様なレイアウトにすることができます。
しかし、他のstyleパラメータを組み合わせた場合は、その組み合わせが複雑になることが多く、見通しが悪くなります。
このカオスなコードは誰が書いたんだー・・・自分でした。。。
ってなことが発生してしまいます。
FlexBoxを使うことで、このような複雑な組み合わせを簡単に実現できます。
簡単な例にはなってしまいますが、例えば、次のような同サイズのボックスを左上に順に表示したり、等間隔に並べたりできます。
FlexBoxの設定の仕方
通常Webの実装では、HTMLの要素にCSSのデザインを当てはめて、Webページを作成していきます。
React NativeではCSSは存在しませんが、同様にstyleを指定してあげることで、画面の整形や装飾をしていきます。
例えば、次のように記述します。
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const Screen = () => {
return (<script type="prism-html-markup">
<View style={ [styles.container, {width: 100%}] }></View></script>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: 'green',
height: '100%',
},
});
export default Screen;
タグの中のoptionとしてstyleを直接指定したり、別途定義したStyleSheetを利用してレイアウトを決定していきます。
この例だと、「backgroundColor: 'green'」を指定したcontainerをstyleに当てているので、画面全体が緑色になります。
FlexBoxで指定できるstyleパラメータは?
詳細は後述しますが、まずは簡単にまとめました。
実際には、動作を確認しながらでないとわかりづらいところもあり、ここではこんなsytle指定ができるんだということを、なんとなく把握してもらえれば良いと思います。
また、要素とは、<View>や<Text>のような1つのタグを意味していると思ってもらえればOKです。
親・子要素の関係は次の場合、
<View>
<Text> Children1 </Text>
<Text> Children2 </Text>
</View>
Viewが親で、2つのTextがそれぞれ子要素となります。
属性 | 説明 | 値 |
---|---|---|
flex | flexDirectionで指定した軸方向に対しての要素サイズの比率を決定する。 | 数字 |
flexDirection | 子要素をどの軸に並べるのかを決定する。列、行方向。 | column, row, column-reverse, row-reverse |
direction | 子要素をどの方向に並べるのかを決定する。右から左、左から右。 | ltr, rtl |
justifyContent | flexDirectionで選択した軸に対して、どのように子要素を並べるかを決定する。 | flex-start, flex-end, center, space-between, space-around, space-evenly |
alignItems | flexDirectionと垂直となる軸に対して、どのように要素を配置するかを決定する。 | stretch, flex-start, flex-end, center, baseline |
alignSelf | alignItemsと同様にどのように要素を置くのかを決定する。alignItemsで指定された要素(コンテナ)に含まれる子要素にalignSelfを指定することで、個別に位置を変えることができる。 | stretch, flex-start, flex-end, center, baseline |
alignContent | flexDirectionと垂直となる軸に対して、どのようにline(要素の列)を並べるかを決定する。alignItemsは要素の塊をどのように配置するか決定していたのに対して、alignContentはline(要素の列)をどのように並べるかを決定する。これは、複数行・列になったとき(flexWarp: warp)に特に力を発揮する。 | flex-start, flex-end, stretch, center, space-between, space-around, space-around |
flexWrap | 子要素が親要素からはみ出た時に折り返すのかを決定する。 | wrap, nowrap |
width, height | 要素の幅、高さを決定する。 | auto, pixels, percentage |
position | 要素の位置を決定する。 | absolute, relative |
flexBasis, flexGrow, flexShrinkもありますが、あまり使われないStyleなので割愛します。
flex
flexは、flexDirectionで指定した軸方向に対しての要素サイズの比率を決定します。
Option
flex
数値を割り当てて画像や図形、領域の比率を決めていきます。
例えば次の例だと、赤・オレンジ・緑の領域で画面が満たされます。
ここでは、赤にはflex:1
、オレンジにはflex:2
、緑にはflex:3
を割り当てています。
そのため、全体は6(=1+2+3)
となり、それぞれの割合は赤:1/6、オレンジ:2/6、緑:3/6となります。
flexDirection
flexDirectionは、要素を整列させる軸を決定します。
Option
column
行方向(縦方向)に要素を整列させます。
先ほどのflex
の例でも、flexDirection: "column"
が指定されていました。row
列方向(横方向)に要素を整列させます。column-reverse
行方向(縦方向)をcolumとは反対に要素を整列させます。row-reverse
列方向(横方向)にrowとは反対に要素を整列させます。
direction
directionは、子要素をどの方向(左→右 or 右→左)に並べるのかを決定します。
Option
ltr
左から右へと要素を並べていきます。おそらくltrは「left to right」の略でしょう。rtl
rtlとは反対に右から左へと要素を並べていきます。rtlは「 right to left」の略でしょう。
justifyContent
justifyContentは、flexDirection
で選択した軸に対して、どのように要素を並べるのかを決定します。
先頭に寄せるのか、後尾に寄せるのか、中央に寄せるのか、等間隔で並べるのかなどを指定できます。
Option
flex-start
指定された軸(flexDirection)の先頭に要素を寄せます。flex-end
指定された軸の後尾に要素を寄せます。center
指定された軸の中央に要素を集めます。space-between
要素間のスペースが均等になり、先頭と後尾の要素は親要素とのスペースが0となります。space-around
要素間のスペースが均等になり、先頭と後尾の要素は親要素とのスペースがす少しできます。space-evenly
先頭・後尾の親要素とのスペースも含めて、要素間のスペースが均等になります。
alignItems
alignItemsは、flexDirection
と垂直となる軸に対して、どのように要素を配置するかを指定します。
Option
stretch
flexDirectionと垂直軸方向に要素を目一杯引き伸ばします。flex-start
flexDirectionと垂直軸の先頭に要素を配置します。flex-end
flexDirectionと垂直軸の後尾に要素を配置します。center
flexDirectionと垂直軸の中央に要素を配置します。baseline
baselineに関しては後述します。
今回の実装例だと、ボックスのサイズが指定されているものもあるので、stretch
を選択しても一部のみサイズが変化します。
alignSelf
alignSelfは、alignItems
と同様なOptionを選択できます。
alignItemsと異なる点としては、ひとつひとつの子要素に対してstyleを指定することができます。
また、alignItemsで指定されてたstyleは、alignSelfで上書きされます。
基本的なレイアウトはalignItemsで指定しておきながら、例外となるところだけalignSelfで位置を変えるという時に便利ですね。
alignContent
alignContentは、flexDirection
の垂直軸に対して、どのように並べるのかを決定します。
これは、justifyContent
の垂直バージョンのstyleで、同様なOptionを選択できます。
複数行・列で効果を発揮するので、次で紹介するflexWrap
がwrap
である必要があります。
Option
flex-start
軸の先頭に要素を寄せます。flex-end
軸の後尾に要素を寄せます。center
軸の中央に要素を集めます。space-between
要素間のスペースが均等になり、先頭と後尾の要素は親要素とのスペースが0となります。space-around
要素間のスペースが均等になり、先頭と後尾の要素は親要素とのスペースがす少しできます。space-evenly
先頭要素と後尾要素の親要素とのスペースも含めて、要素間のスペースが均等になります。
flexWrap
flexWrapは、子要素が親要素からはみ出た時に折り返すのかを決定します。
Option
wrap
親要素から、はみ出した子要素を折り返します。nowrap
親要素から、はみ出しても折り返しません。
width, height
width, heightは、要素の幅や高さを決定します。
通常CSSにおいて「width/height」や次に出てくる「position」はFlexBoxには入らないと思っていましたが、React NativeのFlexBox説明ページには記載されていたので、こちらも掲載しておきます。
サイズの指定の仕方は、auto、pixels、percentの3つになります。
Option
auto
子要素やテキスト、写真のサイズに合わせて、自動で幅・高さが計算されます。pixels
通常のCSSとは異なり、pixelsは記述せず、数値のみを記述します。例えば、幅5pixelサイズにしたい場合はwidth: 5
といった形で記述していきます。percent
こちらは通常のCSSと同じように数値のあとに%
を記述します。これにより、親要素に対しての比率でサイズを指定することができます。
position
positionは、要素の位置を指定するために基準位置を決定します。
要素の位置は、top、bottom、left、rightで決定されますが、その基準となる位置です。
Option
relative
基準位置を相対位置とします。例えば、justifyContent: flex-start
の場合、位置を何も指定しなければ左上に隙間なく要素が並びますが、ここで子要素にtopやleftなどを指定することで、その位置から相対的に要素を移動させることができます。absolute
基準位置を絶対位置とします。親要素の左上をtop: 0; left: 0
の状態として、全ての子要素がtopやleftなどの指定によって左上からの位置を決定します。
番外編:baselineとは?
alignItemsでは、baselineというoptionがありました。
baselineとは、テキストを綺麗に整列させるための基準ラインのことを指します。
中学生でアルファベットを学習した時、行の上下のラインを含めて1行に4つのラインのあるノートを利用して、書き方を習ったと思います。
基本的には、下から2本目のラインにアルファベットの下部を合わせて記述していきます。
このラインのことをbaselineといいます。
alignItemsの実装例を、flexDirection: row
に指定し、さらに、それぞれの要素に異なるサイズの文字を載せると、その違いがわかりやすくなります。
下記の実装例で、「baseline」を選択してもらうと、実際にbaselineを基準に子要素が整列されるのがわかるかと思います。
まとめ:FlexBoxは便利
FlexBoxについて解説していきました。
できることが多くて、少し慣れも必要ですが、画面を綺麗に見せるために強力な機能です。
もう少し詳しく知りたい方は本家のページをご覧ください。
また、上の実装例は、その場でコードを書き換えることもできるので、色々書き換えてみて遊んでみて下さい。