70個react-native flex佈局栗子,肯定有你要的

stupidWall發表於2018-11-28

flex

開發遇到

在開發中,flex佈局用的非常頻繁,每次使用的時候都編寫自己私有的flex樣式會比較麻煩。當然了,因為react-native開發中樣式也是一個物件,可以預設一些常用的flex樣式, 使用的時候直接用即可。

怎麼方便一點

在開發過程中,當我編寫父容器的時候,其實我已經知道自己希望的,裡面子容器佈局是怎樣的,比如

<View style={styles.flex1}>
    <View>A</View>
    <View>B</View>
</View>
複製程式碼

我希望flex1佈局下,裡面的子容器沿著橫軸上下左右居中,於是我會寫下

...
flex1: {
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center'
}
...
複製程式碼

那麼問題來了,我已經很好的理解了flex中父容器各個屬性的用法,我想跟著我的思路寫樣式名,就能出來我要的佈局,不需要重新預定義類似flex1這樣的樣式,那不是挺好的,問題是怎麼優化一下?

指令碼生成所有組合

我自己定好一個規則,如果我寫下面這樣

<View style={styles.flex_row_center_center}>
</View>
複製程式碼

意味著我要的是橫向為主軸,主軸、側軸居中

<View style={styles.flex_row_between_center}>
</View>
複製程式碼

意味著我要的是橫向為主軸,主軸左右對其,側軸居中

......

即 flex_方向_主軸_側軸

按著這個思路,把flexDirection、justifyContent、alignItems在react-native有效的屬性值列出來

flex-direction: ['row', 'column']
justifyContent: ['center', 'space-between', 'space-around', 'flex-start', 'flex-end', 'space-evenly']
alignItems: ['start', 'end', 'center', 'baseline', 'stretch', 'between', 'around']
複製程式碼

通過一個指令碼生成一個類似下面這樣的物件

{
    flex_row_center_center: {
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center'
    },
    ...
}
複製程式碼
const getFlexLayoutStyles = () => {
  /*
    flex_方向_主軸_側軸
  */
  // space-evenly flex容器起始邊緣和第一個 flex 項之間的間距和每個相鄰 flex 項之間的間距是相等
  const DIRECTIONS = ['row', 'column'],
        JUSTIFY_CONTENT_PROPVALUES = ['center', 'space-between', 'space-around', 'flex-start', 'flex-end', 'space-evenly'],
        JUSTIFY_CONTENT_NAMEVALUES = ['center', 'between', 'around', 'start', 'end', 'evenly'],
        ALIGN_ITEMMS_PROPVALUES = ['flex-start', 'flex-end', 'center', 'baseline', 'stretch'],
        ALIGN_ITEMMS_NAMEVALUES = ['start', 'end', 'center', 'baseline', 'stretch', 'between', 'around']
        DIVISION = '_'
        layoutStyles = {};
  let styleName = 'flex'
  DIRECTIONS.forEach((direction) => {
    // flex_row
    const nameDir = styleName + DIVISION + direction
    JUSTIFY_CONTENT_PROPVALUES.forEach((jItem, jIdx) => {
      // flex_row_center
      const nameJust = nameDir + DIVISION + JUSTIFY_CONTENT_NAMEVALUES[jIdx]
      ALIGN_ITEMMS_PROPVALUES.forEach((aItem, aIdx) => {
        // flex_row_center_center
        const nameAlig = nameJust + DIVISION + ALIGN_ITEMMS_NAMEVALUES[aIdx]
        layoutStyles[nameAlig] = {
          flexDirection: direction,
          justifyContent: jItem,
          alignItems: aItem
        }
      })
    })
  })
  console.log('layoutStyles', layoutStyles)
  return layoutStyles
}
複製程式碼

最後列印出來看看layoutStyles是否是我們需要的

70個react-native flex佈局栗子,肯定有你要的

總共60條資料

遍歷所有組合並渲染

...
{
  Object.keys(getFlexLayoutStyles()).map((o, i) => (
    <View style={[styles.demoBox, styles[o], {position: 'relative'} ]} key={i}>
        <Text style={{ position: 'absolute', color: '#fff', left: 0, top: 0, zIndex: 20}}>{ i + 1 }. {o}</Text>
        <View style={[styles.demoItemA,(o.indexOf('stretch') != -1 && o.indexOf('row') != -1) && {height: 'auto'},(o.indexOf('stretch') != -1 && o.indexOf('column') != -1) && {width: 'auto'}, (o.indexOf('baseline') != -1 && o.indexOf('row') != -1) && {height: 80}, (o.indexOf('baseline') != -1 && o.indexOf('column') != -1) && {width: 80}]}>
          {o.indexOf('baseline') != -1 && (<Text style={{color: '#fff'}, o.indexOf('row') != -1 && {marginTop: 20}}>text</Text>)}
        </View>
        <View style={[styles.demoItemB,(o.indexOf('stretch') != -1 && o.indexOf('row') != -1) && {height: 'auto'},(o.indexOf('stretch') != -1 && o.indexOf('column') != -1) && {width: 'auto'}]}>
          {o.indexOf('baseline') != -1 && (<Text style={{color: '#fff'}}>text</Text>)}
        </View>
    </View>
  ))
}
...
複製程式碼

其中,對於子容器的屬性,可以自己根據需要新增即可,譬如,上面的程式碼中,stretch的情況下,判斷出來,需要把子容器原來固定寬高的值,改為'auto',最後看到拉伸填充整個父容器的效果。

space-evenly

70個react-native flex佈局栗子,肯定有你要的

一眼看過去跟,space-around方式很像,仔細看,其實這個的特點是,灰色的區域三等份,開發中很多時候需要這種效果。

baseline

70個react-native flex佈局栗子,肯定有你要的

很像什麼flex-start的效果,其實這個的特點是以'text'第一個文字為基準對其。 如果沒有文字,那效果看起來跟flex-start是一樣的。

alignSelf

70個react-native flex佈局栗子,肯定有你要的

上面三個栗子,父容器的佈局都是flex_row_center_center, 然而對於黑色框的子容器分別設定了alignSelf

# 1
{alignSelf: 'flex-start'}
# 2
{alignSelf: 'flex-end'}
# 3
{alignSelf: 'stretch'}
複製程式碼

可以這樣理解,alignSelf會覆蓋,父容器設定的alignItems走向

理解了這一點,那縱向為主軸也是一個意思, 看下圖

70個react-native flex佈局栗子,肯定有你要的

flex值

70個react-native flex佈局栗子,肯定有你要的

有5個容器,分別設為

flex: 1
flex: 2
flex: 1
flex: 2
flex: 1
複製程式碼

父容器會把自己分為7等份,1,3,5佔1份,2,4佔2份

原始碼

flex佈局GITHUB程式碼

歡迎start, 3Q~~!

掃碼關注個人微信訂閱號

70個react-native flex佈局栗子,肯定有你要的