Expo React Native 之 Flexbox

工程師卡卡
9 min readJun 21, 2021

--

今天主要是來了解 Flex 彈性盒子在 React Native的使用

介紹 主軸相交軸 以及

flex/justifyContent/alignItem/flexDirection/flexWrap

Step1 : 建立一個彩色吧!用這個來練習Flexbox

  1. 先下載 my-expo-exercise 或是起一個新的expo專案
  2. yarn
  3. expo start

Let’s go!

首先先建立components資料夾,在裡面創建一個flex1.js的檔案,如下:

import React from 'react';import { StyleSheet, Text, View } from 'react-native';export default function Flex1() {return (<View style={styles.container}>  <Text>漢堡</Text>  <Text>三明治</Text>  <Text>薯條</Text>  <Text>熱狗</Text>  <Text>太陽蛋</Text></View>);}const styles = StyleSheet.create({container: {},});

並將檔案引入App.js

import React from 'react';import Flex1 from "./components/Flex1"export default function App() {return (<Flex1 />);}
完成步驟一的畫面

Step2 : 了解彈性盒子 Flexbox

排版聖品彈性盒子 Flexbox 是一個可以讓元素膨脹來填充額外空間或著縮小以適應更小的空間的樣式。

首先我們先來了手機裝置中預設的主軸與次軸(與大網的相反),如下圖:

截自https://kknews.cc/code/grv4v8.html

主軸(main-axis):當宣告屬性值 flex 後,預設中主軸會朝向 flexDirection 的設定,預設為垂直排列 column

相交軸(cross axis):又稱次軸,為彈性項目的"換行方向"。也就是說如果彈性項目單行的數量多到超過容器,你想要讓它換行,會遵 flexDirection 的設定相反方向換行,也就是主軸為垂直排列,換行將會是水平換行 row

tips: 當 flexDirection: "column" 考慮寬度 ; flexDirection: "row" 考慮高度。

Flexbox 在 React Native 使用方式

使用方法原理雷同css的style,但是也有少許的差異如下:
  • flexDirection 預設為column
  • 沒有 :focus, :hover, animations, keyframes, transitions
  • 所有的標籤都是使用“display: flex”沒有grid/block/inline display
  • RN 沒有css的小孩選擇器 selectors
  • alignItems 預設為stretch
    alignItems 要有作用(stretch,填好填滿),子元素必須沒有設定對應 cross axis(相反基準線)的寬度(或高度)才會有作用。
  • order < — React Native 中沒有這個屬性。
  • flex 只能用一個數字,flex-flow <— React Native 中沒這個屬性。
    正數代表元件是有”彈性的”,會隨著尺寸等比例放大,例如設為 2 的元件佔的大小是 1 的兩倍。類似於flexGrow
    0為預設,代表元件沒有彈性,只是對應所設置的寬與高度。
    當為-1時,代表元件一般情況對應所設置的寬與高度,當空間不足時會縮小(shrink)到 minWidth 與 minHeight。類似於flexShrink

如果你想要某個元件佔 25%,另一個元件佔 75%,就用flex: 1/4flex: 3/4分別指定兩個元件。

tips:
React Native 中自 0.42 版後才加入 flexGrow、flexShrink、flexBasis 這三個屬性,無法像css一樣簡寫在flex一起使用。

Flexbox 彈性盒子

之所以叫盒子,就是要將彈性項目(子項目)放入這個盒子裡面也就是容器,所以擁有 display:flex 屬性的標籤會是彈性項目們(子項目們)的容器(爸爸)。

請看下方的code,Flex 屬性該放在哪呢?

<View style={styles.container}>
<Text>漢堡</Text>
<Text>三明治</Text>
<Text>薯條</Text>
<Text>熱狗</Text>
<Text>太陽蛋</Text>
</View>

爸爸是<View>tag;子項目們是<Text>tag,所以flex會設定在<View>tag!

View 標籤的原始碼

tips:由瀏覽器 F12來看檢視程式碼(如左圖)原生<View>及<Body>就已經寫上styledisplay:flex
爸爸已經有flex屬性,再來就是設定其他的樣式。

flex / justifyContent/ alignItem / flexDirection / flexWrap

clone 下來裡面的 App.js 可以看到 StyleSheet , 裡面的 flex / alignItems / justifyContent 各是什麼意思呢?

const styles = StyleSheet.create({container: {   flex: 1, 
//flex 決定此元素在頁面可用的區域,切成幾塊1 = 1塊,所以一整塊都是此元素的
backgroundColor: '#fff',
//backgroundColor 背景色
alignItems: 'center',
//alignItems 子項目對齊方式(相交軸)
justifyContent: 'center',
//justifyContent 子項目對齊方式(主軸)
},});

開始來介紹 flexbox 中的 style

  • flexWrap:是代表一條軸線排不下時,是否要換行。這是用於容器的屬性(爸爸)。
    1. 不換行 :nowrap代表這個容器中的項目是只能擠在同一行之中。(圖1)
    2. 換行:wrap則是允許多行。(圖1)
    3. wrap-reversewrap 一樣可以允許多行,但排列會相反。(圖2)
tips: wrap 屬性須在容器屬性(爸爸)裡,搭配flexDirection:'row',才會有感
在row狀態,上面為nowrap下面為wrap(圖1)
在row狀態,上面是wrap-reverse下面是wrap(圖2)
  • align-items、align-self、align-content:是”對齊方式”的意思。而align-self 是用於彈性項目的屬性(子項目)預設為stretch,是填滿的意思。align-items 跟 align-content 則是用於容器的屬性(爸爸),都是應用在 cross axis(相交軸)時。
    1. align-self:為子項目在cross axis(相交軸)的對齊方式。(下面圖3)
    藍色:flex-start
    紅色:center
    橘色:flex-end
    黃色綠色:stretch
    2. align-content:只有在項目被 flexWrap 包裹(wrapped)成為多行排列時,才會發生作用。
(圖3)
  • justify-content: ”對齊”的意思,它是用在 main axis(主軸)時的對齊。這是用於容器的屬性(爸爸)。
    1. flex-start(默認值)
    2. flex-end
    3. center
    4. space-between
    5. space-around:兩端對齊,項目之間的間隔都相等。
    6. space-evenly:伸縮項目會平均地分布在行里,兩端保留一半的空間。
  • grow/shrink/basis: 這三個是用於子項目的”彈性”屬性,也就是在版面或外部容器的尺寸變動時,子項目應該如何隨之進行變動。設定在子項目。
    1. grow 當有空間時,先”變大”的意思。
    2. shrink 當畫面不足時,先”縮水”的意思。
    3. basis ”標準”的意思。
  • flex-direction:為排列方向,預設排列為垂直排列column。
row 水平排列
column 垂直排列
  1. row 水平排列
  2. column 垂直排列
  3. column-reverse 垂直反方向牌
  4. row-reverse 水平反方向著排
# 排列方向:
flexDirection: 'column' || 'row'
# 主軸對齊(爸爸):
justifyContent: 'flex-start' || 'flex-end' || 'center' || 'space-around' || 'space-between'
# 交叉軸對齊(爸爸):
alignItems: 'stretch' || 'flex-start' || 'flex-end' || 'center'
# 交叉軸子項目對齊(子):
alignSelf: 'flex-start' || 'flex-end' || 'center' || 'stretch' || 'auto'
# 換行(爸爸):
flexWrap: 'nowrap' || 'wrap' || 'wrap-reverse'
# Define relative fluidity of an element(爸爸):
flex: number (e.g. 1, 1/2)
#當空間不足,子項目長大縮小(子):
flexGrow/flexShrink: 1 || 0

--

--

工程師卡卡
工程師卡卡

Written by 工程師卡卡

Frontend developer Swift baby level

No responses yet