[React Native Android 安利系列]FLEX佈局精講

歡迎你們收看react-native-android系列教程,跟着本系列教程學習,能夠熟練掌握react-native-android的開發,你值得擁有:
https://segmentfault.com/blog...css

1. FLEX是什麼?

flex佈局,本是一種新的css解決方案,它是『彈性佈局』的縮寫。咱們上一節講到過盒子模型,這個模型的值都是定死的,並不具有可伸縮的性質,因此,應對不一樣屏幕,作到響應式佈局,就很困難。
可是flex佈局,給了咱們一種全新的解決方案,從定位方式,到寬高設置,均可以作到爲所欲爲。
好比:flex佈局能夠指定元素寬或者高相對於同級的比例,而不是定值。react

2. react-native中的flex

咱們先來看看,上一節中提到的,react-native支持的flex佈局的一些屬性吧:android

屬性值 含義
alignItems flex佈局元素中,子元素沿縱軸排列方式
alignSelf flex元素中,本項元素的縱軸對其方式
flex 這裏指代flex-grow,描述了元素的寬度比例值
flexDirection 指代flex元素的排列方向
flexWrap 指代flex元素的換行方式,取值爲 nowrap/wrap
justifyContent 指代flex元素在橫軸上的排列方式,以後會進行詳解

能夠說,react-native對於flex佈局的支持仍是比較全面的,少了幾個簡寫的屬性,很是的簡潔、使用。並且,排布與css的flex佈局基本一致。接下來,咱們將對這些屬性進行一一講解與實踐。segmentfault

2.1 flexDirection屬性

flex元素的排列方向,取值有:column|rowreact-native

2.1.1 column排布(默認)

縱軸排列,豎向排列(如圖2.1.1所示):frontend

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.avatar}>
                    <Image
                        source={myAvatar}
                        style={styles.avatar}
                    />  
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>姓名:一筒</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    shadowBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
        elevation: 5,
    },  
    avatarArea: {
        width: 300,
        height: 300,
    },  
    avatar: {
        resizeMode: Image.resizeMode.contain,
    }   
});

clipboard.png
圖2.1.1佈局

2.1.2 row排布

橫向排列,如圖2.1.2所示學習

container: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: '#fff',
},

clipboard.png
圖2.1.2flex

2.2 flexWrap屬性

flex佈局的換行行爲,取值有:nowrap | wrapspa

2.2.1 nowrap排布

不換行(默認),效果如圖 2.2.1所示:

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.avatar}>
                    <Image
                        source={myAvatar}
                        style={styles.avatar}
                    />  
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>姓名:一筒</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>姓名:一筒</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>姓名:一筒</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>姓名:一筒</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        backgroundColor: '#fff',
    },
    shadowBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },
    back1: {
        elevation: 5,
    },
    avatarArea: {
        width: 300,
        height: 300,
    },
    avatar: {
        resizeMode: Image.resizeMode.contain,
    }
});

clipboard.png
圖 2.2.1
咱們看到,使用了此取值,就算元素寬度超出,也未對元素進行換行。

2.2.2 wrap 換行,效果如圖2.2.2所示:

container: {
    flex: 1,
    flexDirection: 'row',
    flexWrap: 'wrap',
    backgroundColor: '#fff',
},

clipboard.png
圖2.2.2

目測react-native對於換行的元素,採起的措施是隱藏。

2.3 alignItems屬性

flex佈局元素中,子元素沿當前軸的交叉軸的排列方式。取值:'flex-start', 'flex-end', 'center', 'stretch'。請注意,這裏說的是『當前軸的交叉軸』,flexDirection的值爲row的話,元素爲橫向排列,則alignItems控制元素的上下對齊方式。flexDirection的值爲column的話,alignItems控制元素的左右最起方式。

2.3.1 flex-start(默認)

全部子元素排列在主軸開始處,flexDirection爲row時效果如圖2.3.1.1所示:

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.avatar}>
                    <Image
                        source={myAvatar}
                        style={styles.avatar}
                    />
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>姓名:1筒</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>姓名:2筒</Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        backgroundColor: '#fff',
    },
    shadowBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },
    back1: {
        height: 200,
    },
    avatarArea: {
        width: 300,
        height: 300,
    },
    avatar: {
        resizeMode: Image.resizeMode.contain,
    }
});

clipboard.png
圖2.3.1.1
flexDirection爲column時效果如圖2.3.1.2所示:
clipboard.png
圖2.3.1.2

2.3.2 flex-end

全部元素按照主軸結尾處排列,flexDirection爲row時效果如圖2.3.2.1所示:

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'flex-end',
        backgroundColor: '#fff',
    },
    .....

clipboard.png
圖2.3.2.1
flexDirection爲column時效果如圖2.3.2.2所示:
clipboard.png
圖2.3.2.2

2.3.3 center

全部元素居中對齊,如圖2.3.3所示:

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'center',
        backgroundColor: '#fff',
    },
.....

clipboard.png
圖2.3.3

2.3.4 stretch屬性

在當前軸的交叉軸上,進行拉伸。若是元素沒有設置寬度或者高度的話,則使用該值時,將會被拉伸。
咱們將上述例子的alignItems換位stretch,效果如圖2.3.4.1所示(flexDirection爲row):

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.avatarArea}>
                    <Image
                        source={myAvatar}
                        style={styles.avatar}
                    />
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text style={styles.text1}>姓名:1筒</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text style={styles.text2}>姓名:2筒</Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'stretch',
        backgroundColor: '#fff',
    },
    shadowBlock: {
        backgroundColor: '#0f0',
    },
    back1: {
    },
    text1: {
        height: 100,
    },
    text2: {
        height: 200,
    },
    avatarArea: {
        backgroundColor: '#000'
    },
    avatar: {
        resizeMode: Image.resizeMode.contain,
    }
});

clipboard.png
圖2.3.4.1
咱們看到,幾個子元素,高度均被拉伸。
flexDirection換爲column的話,則元素被橫向拉伸(如圖2.3.4.2):
clipboard.png
圖2.3.4.2

2.4 justifyContent屬性

justifyContent控制了元素在當前軸上的排列方式,當前軸有多是column也有多是row,下面以當前軸爲row的狀況作例子,column的狀況,讀着能夠本身試着作作例子。另外注意,這個屬性是設置在全部想排列的子元素的父級元素上的。
justifyContent可選的值有

屬性值 含義
flex-start 在當前軸開始處按序排列(默認)
flex-end 在當前軸結尾處,開始按序排列
center 在當前軸居中位置,兩側伸展排列
space-between 全部元素打散,填充滿整個當前軸,兩側無留白。
space-around 全部元素打散,填充滿整個當前軸,兩側有留白。

2.4.1 flex-start佈局

效果如圖2.4.1所示
clipboard.png
圖2.4.1

2.4.2 flex-end佈局

如圖2.4.2所示,元素都彙集到了當前軸(row)的結尾處:
clipboard.png
圖2.4.2

2.4.3 center佈局

在當前軸居中,並兩側伸展排列,justifyContent: 'center', 如圖2.4.3所示
clipboard.png
圖2.4.3

2.4.4 space-between佈局

全部元素,填充滿整個屏幕,元素與元素間的留白,平均分佈,而且最左邊的元素與最右邊的元素兩側不加留白。justifyContent: 'space-between'如圖2.4.4所示:
clipboard.png
圖2.4.4

2.4.5 space-around佈局

與space-between相似,只不過,使用此屬性時,排列元素兩側也會有留白,最終效果會使全部元素的左右兩側留白均一致。
clipboard.png
圖2.4.5

2.5 alignSelf屬性

該屬性其實與alignItems的屬性鎖表達的意義一致,是不過alignItems應用於父級元素上,決定了全部子元素的排布方式,而alignSelf應用於單個子元素上,決定了子元素本身的對其方式。
其取值與alignItems同樣,也有 'flex-start', 'flex-end', 'center', 'stretch'。只是多了一個值'auto',此值意味着,採用父級元素的alignItems所定義的對其方式。
如,咱們在父級元素上,定義了alignItems爲center,因而咱們看到,這個center被"雨露均沾"到各個子元素上(如圖2.5.1所示):

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.avatarArea}>
                    <Image
                        source={myAvatar}
                        style={styles.avatar}
                    />
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text style={styles.text1}>姓名:1筒</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text style={styles.text2}>姓名:2筒</Text>
                </View>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'center',
        backgroundColor: '#fff',
    },
    shadowBlock: {
        backgroundColor: '#0f0',
    },
    back1: {
        height: 100,
        width: 100,
    },
    text1: {
        height: 100,
        width: 100,
    },
    text2: {
        height: 200,
    },
    avatarArea: {
        width: 100,
        height: 100,
        backgroundColor: '#000'
    },
    avatar: {
        resizeMode: Image.resizeMode.contain,
    }
});

clipboard.png
圖2.5.1
但是有個子元素非是不聽呢,它設置了alignSelf爲flex-start(self這個詞彰顯了個性),因而他就"獨得恩寵",跑到上面去了,如圖2.5.2所示:

avatarArea: {
        width: 100,
        height: 100,
        //子元素設置了此屬性
        alignSelf: 'flex-start',
        backgroundColor: '#000'
    },

clipboard.png
圖2.5.2

一樣的,咱們能夠指定單個元素對其到開始、結尾、中間....,這就是alignSelf的用法了。

2.6 flex屬性

這個屬性可謂是flex佈局中,很是重要的屬性了。以前的開發方式中,咱們會指定元素的寬度與高度,這樣的寫死的方式,沒法適應各類屏幕下的適配。而指定元素的flex,則能夠達到,元素的寬高,按照比例排布。
flex能夠這樣用,當咱們擁有三個元素時,能夠指定三個元素的比例關係,達到自適應的效果,代碼以下(效果如圖2.6.1所示):    

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.avatarArea}>
                    <Image
                        source={myAvatar}
                        style={styles.avatar}
                    />
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text style={styles.text1}>姓名:1筒</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text style={styles.text2}>姓名:2筒</Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'flex-start',
        backgroundColor: '#fff',
    },
    shadowBlock: {
        backgroundColor: '#0f0',
    },
    back1: {
        // 指定後兩個元素的flex值爲2
        flex: 2,
    },
    text1: {
    },
    text2: {
        height: 200,
    },
    avatarArea: {
        // 指定第一個元素的flex值爲1
        flex: 1,
        backgroundColor: '#000'
    },
    avatar: {
        resizeMode: Image.resizeMode.contain,
    }
});

clipboard.png
圖2.6.1

咱們能夠看到,此時元素的比例化爲了1:2:2,這樣佈局,換了大屏幕的手機也依然會保持,媽媽不再用擔憂個人屏幕適配了。

3. 今日做業

請使用flex佈局完成一個相似於手機百度首頁FEED流佈局的界面。

這一章,咱們一塊兒學習了flex佈局的全部屬性,下一章咱們一塊兒來作個例子,實現的就是今天的做業--手機百度上面新聞流的佈局。
形式大概就是這樣:

clipboard.png

原創文章,版權全部,轉載請註明出處

相關文章
相關標籤/搜索