programming

Javascript/Typescript ReactNative Tech

【React Native】画像や図形の自動レイアウト(FlexBox)

2021年10月2日

「画面サイズに合わせて画像や図形を調整したい」

HTMLではFlexBoxを使うことで、画像や図形、領域をアイテム数に合わせて適当なサイズに自動調整することができます。

React Nativeでも同様にFlexBoxを指定することができます。

今回は、本家React Nativeのドキュメントとサンプルコードを参考にしながら、FlexBoxを紹介していきます。

また実装の紹介にはExpoを利用しています。

programming
【React Native】Expoを利用して簡単にアプリ共有

ロナえるも夫です。 「自分のコードの実行結果をブログに表示したい」 という人のために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がそれぞれ子要素となります。

属性説明
flexflexDirectionで指定した軸方向に対しての要素サイズの比率を決定する。数字
flexDirection子要素をどの軸に並べるのかを決定する。列、行方向。column, row, column-reverse, row-reverse
direction子要素をどの方向に並べるのかを決定する。右から左、左から右。ltr, rtl
justifyContentflexDirectionで選択した軸に対して、どのように子要素を並べるかを決定する。flex-start, flex-end, center, space-between, space-around, space-evenly
alignItemsflexDirectionと垂直となる軸に対して、どのように要素を配置するかを決定する。stretch, flex-start, flex-end, center, baseline
alignSelfalignItemsと同様にどのように要素を置くのかを決定する。alignItemsで指定された要素(コンテナ)に含まれる子要素にalignSelfを指定することで、個別に位置を変えることができる。stretch, flex-start, flex-end, center, baseline
alignContentflexDirectionと垂直となる軸に対して、どのように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を選択できます。

複数行・列で効果を発揮するので、次で紹介するflexWrapwrapである必要があります。

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といいます。

抜粋:Qumeru CSSのテキストのベースライン(baseline)とは?

alignItemsの実装例を、flexDirection: rowに指定し、さらに、それぞれの要素に異なるサイズの文字を載せると、その違いがわかりやすくなります。

下記の実装例で、「baseline」を選択してもらうと、実際にbaselineを基準に子要素が整列されるのがわかるかと思います。

まとめ:FlexBoxは便利

FlexBoxについて解説していきました。

できることが多くて、少し慣れも必要ですが、画面を綺麗に見せるために強力な機能です。

もう少し詳しく知りたい方は本家のページをご覧ください。

また、上の実装例は、その場でコードを書き換えることもできるので、色々書き換えてみて遊んでみて下さい。

-Javascript/Typescript, ReactNative, Tech,
-, , , , , , , ,