[React Native Android 安利系列]樣式與佈局的書寫

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

react-native-android的佈局不一樣於以往的網頁佈局,採用的是一種組件的方式,使用js來定義樣式表。接下來,咱們會一塊兒詳細的瞭解這些react-native的樣式,及全部樣式的做用、用法。而且,咱們將經過一些小例子,來實踐這些樣式。css

1. react-native中的樣式

打開咱們以前建立的項目,咱們看到,在最下方,是簡單的佈局樣式。形式自己是javascript的對象形式。觀其內容,則是咱們熟悉的css樣式。前端

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },  
  welcome: {
    fontSize: 20, 
    textAlign: 'center',
    margin: 10, 
  },  
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },  
});

而樣式的應用也是web開發者比較熟悉的『內聯style』的方式,如圖1.1
090326_XsAA_1177792.png
圖1.1
在但願應用的標籤上,將style屬性填寫爲咱們建立的styles,這樣就能將樣式應用於咱們的標籤上了。java

可是這裏請注意,有一些細節仍是和普通的css不同的。react

1. react-native的樣式的屬性名,須要使用駝峯方式。android

2. react-native的樣式應用於某一個組件上的話,該樣式不會繼承下去,而是隻應用於設置該style的節點上(Text相關樣式除外,Text嵌套的話,其文字屬性也會應用於子元素)。git

3. react-native的樣式中width/height的單位是DP。並非PX,這點請同窗們注意一下,不然,按照設計圖設計出來的東西會至關的難看。。。。。github

4. 應用於組件的style屬性上的樣式,能夠不止一個,可使用多個,以逗號分隔。如 style={styles.a,styles.b}web

5. 咱們終於能夠在樣式中使用變量啦,好比咱們想要一個元素的寬度等於屏幕的寬度,能夠直接這麼寫:segmentfault

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        width: Dimensions.get('window').width,
    },
});

2. react-native中全部能用到的屬性

接下來咱們來看一下android中,全部咱們能利用的上的屬性吧:

2.1 背景相關(background)

backfaceVisibility 改元素背面面向屏幕時是否可見

backgroundColor 元素的背景色

2.2 佈局相關(flex)

alignItems flex佈局元素中,子元素沿縱軸排列方式

alignSelf flex元素中,本項元素的縱軸對其方式

flex 這裏指代flex-grow,描述了元素的寬度比例值

flexDirection 指代flex元素的排列方向

flexWrap 指代flex元素的換行方式,取值爲 nowrap|wrap|wrap-reverse

justifyContent 指代flex元素在橫軸上的排列方式,以後會進行詳解。

2.3 佈局相關(margin/padding/border)

margin 留白

marginBottom 底部留白

marginLeft 左外留白

marginRight 右外留白

marginTop 上外留白

marginVertical 上下外留白的簡寫,若是marginTop與marginBottom同樣的話,能夠直接用這個值代替

marginHorizontal 左右外留白的簡寫

borderColor 總體邊框顏色

borderRadius 總體邊框的圓角

borderWidth 總體邊框的寬

borderStyle 邊框樣式 dotted solid double dashed等

borderBottomColor 底邊框顏色

borderBottomWidth 底邊框寬度

borderLeftColor 左邊框顏色

borderLeftWidth 左邊框寬度

borderRightColor 右邊框顏色

borderRightWidth 右邊框寬度

borderTopColor 上邊框顏色

borderTopWidth 上邊框寬度

borderBottomLeftRadius 左下角圓角邊框

borderBottomRightRadius 右下角圓角邊框

borderTopLeftRadius 上邊框左圓角

borderTopRightRadius 上邊框右圓角

padding 內留白

paddingBottom

paddingTop

paddingLeft

paddingRight

paddingHorizontal

paddingVertical

height 元素高度,包含padding與border

width 元素寬度,包含padding與border

2.4 定位相關

position

top

right

bottom

left

2.5 文字相關

color

fontFamily

fontSize

fontStyle

fontWeight

textAlign

textDecorationColor

textDecorationLine

textDecorationStyle

letterSpacing

lineHeight

2.6 陰影相關

shadowColor 陰影色IOS only

shadowOffset 陰影距離IOS only

shadowOpacity 陰影透明度IOS only

shadowRadius 陰影半徑 IOS only

elevation 仰角 android only

2.7 其餘

opacity

overflow

resizeMode

rotation

scaleX

scaleY

transform

transformMatrix

translateX

translateY

writingDirection

3 React屬性逐個詳解+示例

3.1 背景相關屬性

3.1.2 backgroundColor 元素的背景色

backgroundColor相信你們並不陌生,就是一個元素的背景色,支持多種值的選擇

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.colorBlock, styles.back1]}></View>
                <View style={[styles.colorBlock, styles.back2]}></View>
                <View style={[styles.colorBlock, styles.back3]}></View>
                <View style={[styles.colorBlock, styles.back4]}></View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    colorBlock: {
        height: 100,
        width: 100,
    },  
    back1: {
        // 普通的16進制值
        backgroundColor: '#000'
    },  
    back2: {
        // 顏色名稱的簡寫
        backgroundColor: 'blue'
    },  
    back3: {
        // 顏色的RGB表示
        backgroundColor: 'rgb(255, 0, 255)',
    },  
    back4: {
        // 顏色的RGBA表示
        backgroundColor: 'rgba(255, 0, 255, 0.5)',
    },
});

效果以下,具體代碼,參見本文後例子中的--index.android.js.backgroundColor(如圖圖3.2.1)
191642_zW5O_1177792.png
圖3.2.1

3.1.1 backfaceVisibility 改元素背面面向屏幕時是否可見

我的感受這裏reactNative在android下的實現的有點BUG,就是這個屬性沒有達到預期的效果,

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.rotateBlock, styles.back1]}>
                    <Text>Hello</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back2]}>
                    <Text>Hello</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back3]}>
                    <Text>Hello</Text>
                </View>
            </View>
        );  
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        marginTop: 50,
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },
    back1: {
        transform: [{rotateY: '135deg'}],
        backfaceVisibility: 'visible'
    },
    back2: {
        backfaceVisibility: 'hidden',
        transform: [{rotateY: '180deg'}],
    },
    back3: {
        backfaceVisibility: 'hidden',
        transform: [{rotateY: '360deg'}],
    },
});

出現的效果如圖3.1.1:
194310_88XY_1177792.png
圖3.1.1
元素的背面也展示了出來。具體詳見本文例子中的:index.android.js.backfaceVisibility。

3.2 佈局相關(flex)

因爲react-native的佈局比較複雜,因此咱們稍後會花費一整篇的篇幅,對其進行講解。

3.3 佈局相關(margin/padding/border)

height,width 沒必要多說。border,padding,margin的基本屬性,作前端的同窗也是輕車熟路了。這裏,給原生開發,而且以前沒有作過前端的同窗們小小的科普一下。
194824_Bd9v_1177792.png
圖3.3
傳統的網頁設計的,使用css的盒子模型,來搭建元素的佈局。如圖3.3所示。一個元素由,內容、填充(內留白)、邊框、邊界(外留白)組成。對應上了咱們這一組 佈局相關的屬性。

3.3.1 讓咱們來作一個盒子模型的示例

首先,咱們設定一個View,寬高都爲100。

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.rotateBlock, styles.back1]}>
                    <Text>Hello</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },
    back1: {
        
    },
});

效果如圖3.3.1所示:
205116_sHAC_1177792.png
圖3.3.1
展現了一個普通的100*100的正方形(如圖3.3.1.1)。
接着,咱們爲其加上50的padding。
205525_8XLS_1177792.png
圖3.3.1.1
發現其寬高並無變,代表咱們這裏的盒子模型其實有別與傳統的盒子模型。它的寬高是包含了padding(內留白)在內的。
咱們接着,將border也加上寬度:

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        padding: 30,
        borderWidth: 10,
        borderColor: '#000',
        backgroundColor: '#0f0',
    },
    back1: {
        
    },
});

會發現,其實寬度*高度(100*100)也是包含了border的(如圖3.3.1.2)。
210413_PIQF_1177792.png
圖3.3.1.2
因此,咱們react-native的盒模型,能夠認爲是border-box的模型。即,width或者height的設定值,包含了padding、border和content。這點,也請有前段開發經驗的同窗注意一下。
咱們再來看一看margin。

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        padding: 30,
        borderWidth: 10,
        borderColor: '#000',
        margin: 10,
        backgroundColor: '#0f0',
    },
    back1: {
        
    },
});

效果如圖3.3.1.3
210845_CKxr_1177792.png
圖3.3.1.3
咱們看到margin並不會被算到width、height的值當中。而是產生了外部留白。

3.3.2 特殊屬性解釋

這裏請注意,marginvVerticl,marginHorizontal這兩個屬性是(marginTop,marginBottom)與(marginLeft,marginRight)的簡寫。

同理可證,paddingVertical,paddingHorizontal。這幾個屬性在css中沒有,可是react提供了更爲簡潔的設置方法。

borderStyle,這個屬性是設置border的展示樣式的。其可取的值有:

'solid'(默認), 'dotted', 'dashed',可是通過本人實驗,在android環境下,幾個屬性貌似不能用。

具體詳見本文例子中的:index.android.js.boxLayout文件。

3.4 定位相關

熟悉前端的同窗確定對position這個屬性特別的親切。這是網頁佈局中很是常見的一種定位方式。而對於不熟悉前端的同窗來講呢,咱們也會一塊兒來看看,這組屬性到底有什麼做用。

一個元素若是不設定position去定位話,默認會造成文檔流。每一個元素會按順序出如今文檔流中,排到本身的位置上。

舉個例子,咱們有三個view,普通排列,正如咱們所想,是一個挨着一個,順序出如今被安排的位置上:

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.rotateBlock, styles.back1]}>
                    <Text>Hello1</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back2]}>
                    <Text>Hello2</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back3]}>
                    <Text>Hello3</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
            
    },  
    back2: {
    },  
    back3: {
            
    },  
});

效果如圖3.4.1
220850_xIDk_1177792.png
圖3.4.1
若是咱們將第二個view的定位設定爲absolute(絕對定位),那麼會變成什麼樣呢,如圖3.4.2?

back2: {
    position: 'absolute',
},

221058_8Z98_1177792.png
圖3.4.2
咱們發現,第二個view不見了,那麼它去哪兒了呢?它已經脫離了咱們的文檔流,留下1和3,還規規矩矩的排在那裏。咱們爲了找到第二個view,目前到底在哪兒,來嘗試着更改其top和left。top/right/bottom/left決定了定位元素的位置。咱們先調整其left爲20,如圖3.4.3

back2: {
    position: 'absolute',
    backgroundColor: '#f00',
    left: 30,
},

222313_B70i_1177792.png
圖3.4.3
可見第二個元素雖然脫離了文檔流可是仍是在原先的位置上。只不過是被後面的第三個view給蓋住了。這和咱們在前端的常識不一樣。不過也能夠理解爲,此時的top與left。設定爲了與本身未脫離文檔流時候的top和left一致。

若是兩個元素都設定爲position:absolute,咱們會看到排列順序是按照文檔流出現的順序,下面的蓋住上面的。可是若是咱們像調整一下覆蓋的順序呢?咱們在這裏要介紹一下elevation,這個屬性,這個屬性比較奇特,他不只能夠控制覆蓋順序(就像z-index那樣),同時會產生一個陰影特效,稍後咱們會講到。

咱們來實驗一下,如圖3.4.4:

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>Hello1</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back2]}>
                    <Text>Hello2</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    shadowBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
        position: 'absolute',
    },  
    back2: {
        position: 'absolute',
    },  
});

232251_E1Kh_1177792.png
圖3.4.4
咱們看到,文檔流中後出現的hello2覆蓋掉了hello1。那麼咱們將兩個元素都設置上elevation屬性,再來看看(如圖3.4.5):

back1: {
    position: 'absolute',
    elevation: 1,
},
back2: {
    position: 'absolute',
},

232708_veq0_1177792.png
圖3.4.5
咱們看到,劇情發生了反轉,有elevation的hello1,覆蓋住了在文檔流中後出現的hello2。其實hello2的elevation值,咱們能夠認爲是0,

結論:當兩個元素,顯示上有重疊的時候,elevation大的元素,會覆蓋掉elevation值較小的元素。

相應的例子代碼,在本文例子中的index.android.js.elevation文件裏。

上面,咱們討論了position爲絕對定位的時候的排布規律,而若是position設定爲relative的話,會怎樣呢(如圖3.4.6)?

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
            
    },  
    back2: {
        position: 'relative',
        backgroundColor: '#f00',
    },  
    back3: {
            
    },  
});

223214_E0n1_1177792.png
圖3.4.6
咱們看到,並無發生什麼異樣,文檔流仍是那個文檔流,but,若是此時,咱們設置了left: 20的話,咱們再來看看效果,如圖3.4.7

back2: {
    position: 'relative',
    left: 20,
    backgroundColor: '#f00',
},

223542_KkX1_1177792.png
圖3.4.7

第二個view並未脫離文檔流,而是按照本身以前的位置,進行了偏移。

如上述所示,其實各位發現react的定位,並不複雜。另外,元素默認的position,是relative,因此其實上面的例子,咱們不用指定position,也能獲得一樣的效果:

back2: {
    left: 20,
    backgroundColor: '#f00',
},

具體代碼詳見本文例子中的:index.android.js.boxLayout文件。

3.5 文字相關

react-native中,文字相關的樣式設定,咱們將會單獨拿出一節來討論。請各位關注,很快就會產出。

3.6 陰影相關

陰影可讓咱們的應用變得更加的立體,呈現出更好的展現效果。讓咱們一塊兒將陰影系列的屬性一一實踐。

shadowColor

shadowOffset

shadowOpacity

shadowRadius

這些屬性,目前只適用於IOS系統,android的話,有一個替代屬性elevation,這個屬性影響着元素的z-index,就是絕對定位時的覆蓋順序(上面咱們提到過),也會在元素上產生一個陰影。

咱們能夠利用這個屬性來設定陰影,elevation的值會影響陰影的offset(如圖3.6.1):

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>Hello1</Text>
                </View>
            </View>
        );  
    }   
}

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

233545_0fUV_1177792.png
圖3.6.1
就這樣,咱們成功的看到了陰影,不過這個屬性要慎用,由於它會影響z軸上的排列順序。

具體代碼詳見本文例子中的:index.android.js.elevation2文件。

3.7 其餘屬性

因爲其餘屬性較爲散亂也較爲複雜,咱們接下來將專門花去一篇的篇幅,來逐一講解這些屬性,請各位看官關注個人博客,很快就會更新。

本文中提到的例子,均在下面的github上,須要的話請下載:

https://github.com/houyu01/re...

接下來,我會詳細的帶你們一塊兒瞭解一下react-native的flex佈局,不要走開,請關注我.......

若是喜歡本文請點擊下方的推薦哦,你的推薦會變爲我繼續更文的動力。

以上內容僅表明筆者我的觀點,若有意見請通知筆者。

相關文章
相關標籤/搜索