React Native之FlexBox介紹與使用_native

來源:互聯網
上載者:User
前言

學習本系列內容需要具備一定 HTML 開發基礎,沒有基礎的朋友可以先轉至 HTML快速入門(一) 學習

本人接觸 React Native 時間並不是特別長,所以對其中的內容和性質瞭解可能會有所偏差,在學習中如果有錯會及時修改內容,也歡迎萬能的朋友們批評指出,謝謝

文章第一版出自簡書,如果出現圖片或頁面顯示問題,煩請轉至 簡書 查看 也希望喜歡的朋友可以點贊,謝謝 什麼是 FlexBox 布局

在 html 中,介面的搭建都是採用 CSS 的布局方式,CSS 是基於盒子模型,依賴於 display、position、float屬性,這對於一些比如 垂直置中 的特殊布局來說非常不方便

Flex 是一種全新的針對 Web 和移動開發的布局方式,它可以簡便、完整、響應式地實現各種頁面配置,並且目前的所有瀏覽器已經支援這種布局方式,所以不用考慮相容性方面的問題

FlexBox 從字面上可以理解成:能夠很容易變化以適應外界條件變化的通用矩形容器,也就是我們常聽到的 彈性布局,它的宗旨就是 通過彈性的方式來第七和分布容器中內容的空間,使其能使用不同螢幕,為盒裝模型提供最大的靈活性(這類似於 iOS 開發中的AtuoLayout布局方式)

FlexBox 布局主要思想是:讓容器有能力讓其子項目改變寬度、高度甚至是順序,從而達到最佳填充可用空間的方式

React Native 中的 FlexBox 是這個規範的一個子集

綜上所述,FlexBox 就是用來解決 父盒子 和 子盒子 之間的約束關係,如下圖

FlexBox 在開發中能夠解決下面等問題 浮動布局 水平和垂直置中 自動分配寬度 各種機型螢幕適配 動態分配子集的尺寸、位置等等

如下圖所示,在 CSS 中,常規的布局是基於塊和內聯流方向,而 Flex布局是基於 Flexflow流【容器預設存在兩根軸:水平的主軸(main axis) 和 垂直的交叉軸(cross axis),主軸的開始位置(與邊框的交叉點)叫做 main start,結束的位置叫 main end;交叉軸的開始位置叫做 cross start,結束位置叫做 cross end。項目預設沿著主軸排列,單個項目佔據的主軸空間叫做 main size,佔據的交叉軸空間叫做 cross size】

根據伸縮項目相片順序的不同,主軸和側軸方向也會變化,如下圖所示

擷取主畫面尺寸

為了後面更好的展示案例,我們先來看看如何擷取主畫面的尺寸和解析度 首先,我們需要先匯入 Dimensions 庫


    // 匯入類庫    var Dimensions = require('Dimensions');
接下來就可以在需要的地方使用 Dimensions 變數擷取螢幕的高度、寬度、解析度等等資料
    export default class TestRN extends Component {        render() {            return (            <View style={styles.container}>                <Text>當前螢幕的寬度:{Dimensions.get('window').width}</Text>                <Text>當前螢幕的高度:{Dimensions.get('window').height}</Text>            </View>            );        }    }
設定樣式
    // 樣式    const styles = StyleSheet.create({        container: {            backgroundColor:'blue'        },    });

效果:

既然能拿到螢幕的尺寸,那麼就能夠直接將主 View 的大小設定成螢幕的尺寸,使 View 填充整個螢幕

    // 樣式    const styles = StyleSheet.create({        container: {            backgroundColor:'blue',            height:Dimensions.get('window').height,            width:Dimensions.get('window').width        },    });

效果:
FlexBox 常用容器屬性

為了方便理解,我們先添加幾個視圖

    // 匯入類庫    var Dimensions = require('Dimensions');    // 入口    export default class TestRN extends Component {        render() {            return (            <View style={styles.container}>                <View style={styles.subViewStyle1}></View>                <View style={styles.subViewStyle2}></View>                <View style={styles.subViewStyle3}></View>            </View>        );    }}    // 樣式    const styles = StyleSheet.create({        container: {            backgroundColor:'blue',            height:Dimensions.get('window').height,            width:Dimensions.get('window').width        },        subViewStyle1: {            backgroundColor:'red',            height:60,            width:60,        },        subViewStyle2: {            backgroundColor:'yellow',            height:60,            width:60,        },        subViewStyle3: {            backgroundColor:'green',            height:60,            width:60,        },    });

效果:

flexDirection(該屬性決定了項目排列的方向,也就是主軸的方向) row:主軸為水平方向,起點在左端


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定主軸方向        flexDirection:'row'    },

效果:
row-reverse:主軸為水平方向,起點在右端


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定主軸方向        flexDirection:'row-reverse'    },

效果:
column(預設):主軸為垂直方向,起點在上


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定主軸方向        flexDirection:'column'    },

效果:
column-reverse:主軸為垂直方向,起點在下


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定主軸方向        flexDirection:'column-reverse'    },

效果:

justifyContent(定義伸縮項目在主軸線的對齊) flex-start(預設):伸縮項目向一行的起始位置靠齊


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定子項目在主軸上的對齊        justifyContent:'flex-start'    },

效果:
flex-end:伸縮項目向一行的結束位置靠齊


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定子項目在主軸上的對齊        justifyContent:'flex-end'    },

效果:
center:伸縮項目向一行的中間位置靠齊


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定子項目在主軸上的對齊        justifyContent:'center'    },

效果:
space-between:左右對齊,項目之間的間隔都相等


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定子項目在主軸上的對齊        justifyContent:'space-between'    },

效果:
space-around:伸縮項目會平均分布在行內,兩端保留一半的空間


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定子項目在主軸上的對齊        justifyContent:'space-around'    },

效果:

alignItems(定義項目在交叉軸上如何對齊,可以把它看成側軸(垂直於主軸)的對齊) flex-start(預設):側軸軸的起點對齊


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定項目在側軸上如何對齊        alignItems:'flex-start'    },

效果:
flex-end:


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定項目在側軸上如何對齊        alignItems:'flex-end'    },

效果:
center:側軸的中點對齊


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定項目在側軸上如何對齊        alignItems:'center'    },

效果:
stretch(預設):如果項目沒有設定高度或設定為 auto,將佔滿整個容器高度


    container: {        backgroundColor:'blue',        注釋掉高度        // height:Dimensions.get('window').height,        // width:Dimensions.get('window').width,        // 設定項目在側軸上如何對齊        alignItems:'stretch'    },

效果:

flexWrap(預設情況下,項目都排在一條軸線上,flex-wrap屬性定義如果一條軸線排不下,如何換行) nowrap(預設):不換行


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定主軸方向        flexDirection:'row',        // 設定換行的方式        flexWrap:'nowrap'    },

效果:
wrap:換行,第一行在上方


    container: {        backgroundColor:'blue',        height:Dimensions.get('window').height,        width:Dimensions.get('window').width,        // 設定主軸方向        flexDirection:'row',        // 設定換行的方式        flexWrap:'wrap'    },

效果:
FlexBox 常用元素屬性

flex(flex-grow、flex-shrink、flex-basis三個屬性的縮寫,第二個參數和第三個參數是選擇性參數):預設值為 “0 1 auto” 寬度 = 彈性寬度 * (flexGrow / sum(flexGorw))(重要) 先來做一下實驗,看看flex到底是幹嘛的,首先,我們先初始化一個新視圖,便於理解


    // 入口    export default class TestRN extends Component {        render() {            return (            <View style={styles.container}>                <View style={{backgroundColor:'red', height:60, width:60}}></View>                <View style={{backgroundColor:'green', height:60, width:60}}></View>                <View style={{backgroundColor:'yellow', height:60, width:60}}></View>            </View>            );        }    }    // 樣式    const styles = StyleSheet.create({        container: {            backgroundColor:'blue',            flex:1,            // 設定主軸方向為水平,起點在左            flexDirection:'row'        },    });

效果:
現在我們給紅色項目設定 flex 為1,可以看到紅色項目的寬度填充了除去 綠色項目和黃色項目 的部分


    <View style={{backgroundColor:'red', height:60, width:60, flex:1}}></View>

效果:
接著再給綠色項目也設定 flex 為1,可以看到紅色項目和綠色項目填充了 除黃色項目 的部分,並且紅色和綠色項目各占剩下空間的一半


    <View style={{backgroundColor:'red', height:60, width:60, flex:1}}></View>    <View style={{backgroundColor:'green', height:60, width:60, flex:1}}></View>

效果:
現在我們再設定黃色項目的 flex 為2,可以看出,紅色和綠色所佔的空間和等同於黃色項目,並且紅色和綠色平分了除黃色項目以外的空間,現在我們應該能理解上面公式的意思了吧(項目寬度 = 父項目的寬度 * (子項目自身比例 / 所有父項目內子項目的比例))


    <View style={{backgroundColor:'red', height:60, width:60, flex:1}}></View>    <View style={{backgroundColor:'green', height:60, width:60, flex:1}}></View>    <View style={{backgroundColor:'yellow', height:60, width:60, flex:3}}></View>

效果:
但是不知道各位發現了沒有,雖然我們每個子項目都同時設定了高度和寬度,但是卻只有寬度改變,而高度則一直保持我們設定的狀態,是不是 flex屬性 只對寬度有效呢。接下來我們來修改下代碼,看看是不是真的如我們想象的這樣 ———— 這裡我們將綠色的高度去掉,可以看出,綠色項目的高度填充了整個父項目的高度


    <View style={{backgroundColor:'red', height:60, width:60, flex:1}}></View>    <View style={{backgroundColor:'green', width:60, flex:1}}></View>    <View style={{backgroundColor:'yellow', height:60, width:60, flex:3}}></View>

效果:
總結以上的樣本,可以看出,不管是否設定子項目的寬度,flex都會忽略寬度,按照上面的公式進行縮放,如果我們設定了高度,那麼 flex 會遵循我們所設定的高度,不去進行展開,反之將會對高度進行展開 根據 flex 的特性,如果沒有設定 View 的尺寸情況下,使用 flex 也可以讓 View 佔滿整個螢幕


    container: {        backgroundColor:'blue',        flex:1    },

alignSelf(允許單個項目有與其它項目不一樣的對齊,可覆蓋 align-items屬性) auto(預設):繼承父元素的alignItems屬性,如果沒有則切換為stretch


    subViewStyle2: {        backgroundColor:'yellow',        height:60,        width:60,        alignSelf:'auto'    },

效果:
flex-start:項目從側軸的起點開始


    subViewStyle2: {        backgroundColor:'yellow',        height:60,        width:60,        alignSelf:'flex-start'    },

效果:
flex-end:項目從側軸的終點開始


    subViewStyle2: {        backgroundColor:'yellow',        height:60,        width:60,        alignSelf:'flex-end'    },

效果:
center:項目以側軸的中心為參照


    subViewStyle2: {        backgroundColor:'yellow',        height:60,        width:60,        alignSelf:'center'    },

效果:
stretch


    subViewStyle2: {        backgroundColor:'yellow',        height:60,        width:60,        alignSelf:'stretch'    },

效果:
我們 FlexBox 的使用就先簡單介紹到這裡,在後續的文章中,會在實際的開發情境中帶大家更多更細緻地講解 FlexBox,如果你覺得哪裡寫得不好或者有誤,麻煩留言或者用郵箱的方式聯絡我,當然遇到問題也可以,最後如果喜歡我的文章,還請點個贊並關注,讀者的肯定是對我們筆者最大的鼓勵,謝謝。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.