JavaScript
reactjs
React
reactnative
react-native

React Native flexプロパティ、段組配置、固定要素配置方法

More than 1 year has passed since last update.

Style プロパティについて

CSSライクなプロパティ群ではありますが、CSSとは異なる場合もあります。

  • flex:number という記述
  • position:'fixed'がない

などなど。
そこで、flexプロパティを解説するとともに、段組や固定要素の配置方法を書いていきたいと思います。

flexプロパティについて

サンプルコードなどをみているとflex:1という記述がよく見受けられます。
flexプロパティは画面上に対する要素のflexDirection方向の大きさの比率となります。

import {StyleSheet} from 'react-native';

const style = StyleSheet.create({
  container:{
    marginTop:20,
    flex:1,
    //flexDirection:'column' ##defaultValue
  }
});

上記の場合に、画面上にflex:1の要素を追加していくと挙動は下記のようになります。

flex.gif

1つしか要素がないときは、画面目一杯に要素が広がります。
2つ以上の要素があるときは、要素の大きさは均等割になります。これは追加される要素のflexの値が等しいためです。

続いて、

  • 最初はflex:1
  • 次はflex:2
  • 次はflex:3
  • 次は・・・・

というように要素を追加していくと挙動は下記のようになります。

flex.gif

すると次は均等割ではなくなります。これは2つ要素がある場合は、1:2の比率で、3つ要素がある場合は1:2:3の比率で・・・といった具合に表示されているためです。

flexDirection:'row'

の場合の挙動は下記のようになります。この時も最初のgifアニメーションと同様にflex:1の要素を追加しています。

flex.gif

以上のようにflexプロパティはflexDirectionに対する比率を決めるプロパティです。
flexプロパティには小数も使用することができますが、基本的な仕様は同じです。

flexを利用した配置方法でヘッダー、フッター、サイドバーを置く

flexを利用した配置方法を使うことで、段組的に配置させることができます。
具体的には

flex.gif

    <View style={{flex:1}}>

        {/*ヘッダー(赤)*/}
        <View style={[{flex:0.3},header]}>
          <Text style={textStyle}>
            This is Header
          </Text>
        </View>

        {/*メインコンテンツ*/}
        <View style={{flex:2, flexDirection:'row'}}>

                    {/*スクロール領域(白)*/}
          <View style={{flex:5}}>
            <ListView
              dataSource={this.state.dataSource}
              renderRow={
                rowData =>
                  (<Text style={{marginLeft:20}}>
                    {rowData.message}
                  </Text>)
              }
            />
          </View>

          {/*サイドエリア(紫)*/}
          <View style={[{flex:1},side]}>
            <Text style={textStyle}>
              This is sidebar
            </Text>
          </View>

        </View>

        {/*フッター(青緑)*/}
        <View style={[{flex:0.5},footer]}>
            <Text style={textStyle}>This is Footer</Text>
        </View>

      </View>

flex関係のプロパティは外出しして書いています。
この場合は、
ヘッダー:メインコンテンツ:フッターのflexプロパティの値は 0.3:2:0.5 なのでこの比率が縦方向長さの比率となります。

続いて、メインコンテンツではflexDirection:'row'が指定されているため、メインコンテンツ内のflexプロパティの比率は横方向の比率となります。よって、メインコンテンツは横方向に
スクロール領域:サイドバー = 5:1 となります。
  
このようにしてflexプロパティを利用することで比率で配置することができます。

固定配置について

React Nativeでは、positionプロパティのプロパティ値は'absolute'と'relative'しか扱うことができず、'fixed'を扱うことができません。
しかし、どれだけ画面上におおきな要素を表示させてもスクロールできない仕様のため、固定要素の表示は簡単に行えます。
スクロールをさせるためにはScrollViewコンポーネントかListViewコンポーネントを使います。

      <View style={{flex:1}}>
          <View style={{
              width:100,
              height:100,
              margin:20,
              top:10,
              backgroundColor:'blue',
              position:'absolute'
            }} />
          <ScrollView>
            {this._renderBox()}
          </ScrollView>
          <View style={{
              width:100,
              height:100,
              margin:20,
              backgroundColor:'red',
              position:'absolute',
              top:300
            }} />
      </View>

flex.gif

この画像では黒い四角があるレイヤーがScrollViewを実装した領域。赤い四角と青い四角がスクロールを実装していないコンポーネントです。
赤と青の四角のようにスクロールを実装しないでスクロール可能領域上に配置することで固定要素を実現できます。

以上です。
間違い等ございましたらご指摘頂けますと幸いです。