LoginSignup
4
4

More than 3 years have passed since last update.

【React Native入門】4-1 レイアウトを考える 基本画面を構成するもの

Last updated at Posted at 2019-10-25

「React Native入門 掌田 津耶乃著」にて動作確認したコードを逐一まとめた記事です。
基本は自分用のメモですので、動作確認したい場合ご利用ください。
ある程度は1記事を更新していき、セッションが切り替わったら別記事に残していこうと思います。

目次
[ P.150〜P.155 ]
・スマートフォンの画面構成
・ステータスバーとヘッダー
・ステータスバーとヘッダーを表示する
[ P.155〜P.159 ] フレックスボックスについて
[ P.159〜P.162 ] flex属性の働き
[ P.162〜P.165 ] flex:0と1の動き


[ P.150〜P.155 ]
・スマートフォンの画面構成
・ステータスバーとヘッダー
・ステータスバーとヘッダーを表示する

[StatusBar コンポーネント]

<StatusBar barStyle=タイプ hidden=真偽値 />

<タイプ>
default
light-content
dark-content

[Header コンポーネント]

<Header
 leftComponent=コンポーネントの設定
 centerComponent=コンポーネントの設定
 rightComponent=コンポーネントの設定
 otherContainerStyles=スタイルの設定
 innerContainerStyles=スタイルの設定
/>
アイコンの表示
{{ icon: アイコン名, color: '色', size: サイズ }}

テキストの表示
{{ text: テキスト, style: スタイル }}
App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, StatusBar, TextInput, Text, View } from 'react-native';
import { Header } from 'react-native-elements';

export default class App extends Component {

  constructor(props) {
    super(props);
    this.title = 'Layout';
    this.state = {
      message: 'This is sample message.',
    }
  }

  render() {
    return (
      <View style={styles.body}>
        <StatusBar barStyle="light-content" hidden={ false } />
        <Header
          leftComponent={{
            icon: 'menu', color: 'white', size: 25,
            onPress: this.doActionLeft
          }}
          centerComponent={{
            text: 'Sample App',
            style: styles.header
          }}
          rightComponent={{
            icon: 'android',
            color: 'white',
            size: 25,
            onPress: this.doActionRight
          }}
          otherContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
          innerContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
        />
        <View style={styles.base}>
          <Text style={ styles.title }>{ this.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
        </View>
      </View>
    );
  }

  doActionLeft = () => { Alert.alert('Left icon tapped!'); }
  doActionRight = () => { Alert.alert('Right icon tapped!'); }

}

const styles = StyleSheet.create ({
  body: {
    height: '100%',
    backgroundColor: '#efecea'
  },
  base: {
    padding: 20
  },
  header: {
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold'
  },
  title: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 25,
  },
  message: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 15, 
  },
});

[ P.155〜P.159 ] フレックスボックスについて

・flexDirection
 row…横方向
 column…縦方向

・justifyContent
 flex-start…開始位置から並べる
 center…中央に並べる
 flex-end…終了位置から並べる
 space-around…絶対を一定幅ごとに分け、その中心に並べる
 space-between…両端から均等に並べる
 space-evenly…両端から同じ幅でスペースをとって並べる

<View style={{
 flexDirection: '方向',
 justifyContent: '位置揃え',
}}>
 ...配置されるコンポーネント...
</View>
App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, StatusBar, TextInput, Text, View } from 'react-native';
import { Header } from 'react-native-elements';

export default class App extends Component {

  constructor(props) {
    super(props);
    this.title = 'FlexLayout';
    this.state = {
      message: 'This is sample message.',
    }
  }

  render() {
    return (
      <View style={styles.body}>
        <StatusBar barStyle="light-content" hidden={ false } />
        <Header
          leftComponent={{
            icon: 'menu', color: 'white', size: 25,
            onPress: this.doActionLeft
          }}
          centerComponent={{
            text: 'Sample App',
            style: styles.header
          }}
          rightComponent={{
            icon: 'android',
            color: 'white',
            size: 25,
            onPress: this.doActionRight
          }}
          otherContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
          innerContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
        />
        <View style={styles.base}>
          <Text style={ styles.title }>{ this.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
          <View style={{
            flexDirection: 'row',
            justifyContent: 'center',
          }}>
            <View style={ styles.view } />
            <View style={ styles.view } />
            <View style={ styles.view } />
          </View>
        </View>
      </View>
    );
  }

  doActionLeft = () => { Alert.alert('Left icon tapped!'); }
  doActionRight = () => { Alert.alert('Right icon tapped!'); }

}

const styles = StyleSheet.create ({
  body: {
    height: '100%',
    backgroundColor: '#efecea'
  },
  base: {
    padding: 5
  },
  header: {
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold'
  },
  title: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 25,
  },
  message: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 15, 
  },
  view: {
    width: 100,
    height: 100,
    margin: 5,
    backgroundColor: '#6666aa'
  }
});

[ P.159〜P.162 ] flex属性の働き

コンポーネントのサイズを割合で変えることができ、
よりフレキシブル(変動)なレイアウトが可能。

flex:整数のみ ※実数は不可

// 比率1:2のレイアウトの場合
<View style={{ flex:1 }} />
<View style={{ flex:2 }} />

// スタイルシート利用の場合
<View style={ styles.view1 } />
<View style={ styles.view2 } />
...
const styles = StyleSheet.create ({
  view1: {
    flex: 1,
  },
  view2: {
    flex: 2,
  },
});
App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, StatusBar, TextInput, Text, View } from 'react-native';
import { Header } from 'react-native-elements';

export default class App extends Component {

  constructor(props) {
    super(props);
    StatusBar.setBarStyle('light-content', true);
    // StatusBar.setBackgroundColor('#008080', true); // Andoroidのみ
    this.title = 'FlexLayout';
    this.state = {
      message: 'This is FlexLayout.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <Header
          leftComponent={{
            icon: 'menu', color: 'white', size: 25,
            onPress: this.doActionLeft
          }}
          centerComponent={{
            text: 'Sample App',
            style: styles.header
          }}
          rightComponent={{
            icon: 'android',
            color: 'white',
            size: 25,
            onPress: this.doActionRight
          }}
          otherContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
          innerContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
        />

        <Text style={ styles.title }>{ this.title }</Text>
        <Text style={ styles.message }>{ this.state.message }</Text>

        <View style={styles.container}>
          <View style={ styles.view1 } />
          <View style={ styles.view2 } />
          <View style={ styles.view3 }>
            <View style={ styles.view4 } />
            <View style={ styles.view4 } />
          </View>
        </View>

      </View>
    );
  }

  doActionLeft = () => { Alert.alert('Left icon tapped!'); }
  doActionRight = () => { Alert.alert('Right icon tapped!'); }

}

const styles = StyleSheet.create ({
  base: {
    flex: 1
  },
  header: {
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold'
  },
  title: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 25,
  },
  message: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 15, 
  },
  container: {
    flex: 1,
    padding: 10,
    margin: 10,
    backgroundColor: '#eeffee',
    borderStyle: 'solid',
    borderWidth: 2,
    borderColor: 'red',
  },
  view1: {
    flex: 1,
    margin: 5,
    backgroundColor: '#6666aa',
    borderStyle: 'solid',
    borderWidth: 2,
    borderColor: 'black',
  },
  view2: {
    flex: 2,
    margin: 5,
    backgroundColor: '#9999cc',
    borderStyle: 'solid',
    borderWidth: 2,
    borderColor: 'black',
  },
  view3: {
    flex: 2,
    flexDirection: 'row',
    margin: 0,
  },
  view4: {
    flex: 1,
    margin: 5,
    backgroundColor: '#ccccff',
    borderStyle: 'solid',
    borderWidth: 2,
    borderColor: 'blue',
  },
});

[ P.162〜P.165 ] flex:0と1の動き

※いまいち使い方わからないため動作確認したコードのみアップしておきます。
個人的感想だと上3つをきっちり理解すればLayoutはできそうな感じがします。

App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, StatusBar, TextInput, Text, View } from 'react-native';
import { Header } from 'react-native-elements';

export default class App extends Component {

  constructor(props) {
    super(props);
    StatusBar.setBarStyle('light-content', true);
    // StatusBar.setBackgroundColor('#008080', true); // Andoroidのみ
    this.title = 'FlexLayout';
    this.state = {
      message: 'This is FlexLayout.',
    }
  }

  render() {
    return (
      <View>
        <Header
          leftComponent={{
            icon: 'menu', color: 'white', size: 25,
            onPress: this.doActionLeft
          }}
          centerComponent={{
            text: 'Sample App',
            style: styles.header
          }}
          rightComponent={{
            icon: 'android',
            color: 'white',
            size: 25,
            onPress: this.doActionRight
          }}
          otherContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
          innerContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
        />

        <View style={styles.base}>
          <Text style={ styles.title }>{ this.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>

          <View style={{
            flex: 1,
            flexDirection: 'row',
            justifyContent: 'flex-end',
            alignItems: 'flex-start',
          }}>
            <View style={ styles.view } />
            <View style={ styles.view } />
            <View style={ styles.view } />
          </View>

          <View style={{
            flex: 0,
            flexDirection: 'column',
            justifyContent: 'flex-start',
            alignItems: 'flex-start',
          }}>
            <View style={ styles.view2 } />
            <View style={ styles.view2 } />
          </View>

          <View style={{
            flex: 1,
            flexDirection: 'column',
            justifyContent: 'flex-start',
            alignItems: 'flex-end',
          }}>
            <View style={ styles.view2 } />
            <View style={ styles.view2 } />
          </View>

          <View style={{
            flex: 1,
            flexDirection: 'column',
            justifyContent: 'flex-start',
            alignItems: 'flex-start',
          }}>
            <View style={ styles.view2 } />
            <View style={ styles.view2 } />
          </View>

        </View>

      </View>
    );
  }

  doActionLeft = () => { Alert.alert('Left icon tapped!'); }
  doActionRight = () => { Alert.alert('Right icon tapped!'); }

}

const styles = StyleSheet.create ({
  base: {
    padding: 5
  },
  header: {
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold'
  },
  title: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 25,
  },
  message: {
    padding: 10,
    color: '#3a3c49',
    fontSize: 15, 
  },
  view: {
    width: 100,
    height: 100,
    margin: 5,
    backgroundColor: '#6666aa',
  },
  view2: {
    width: 45,
    height: 45,
    margin: 5,
    backgroundColor: '#9999ff',
  },
});
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4