入門
Props屬性
大多數(shù)組件在創(chuàng)建時就可以使用各種參數(shù)來進(jìn)行定制露戒。用于定制的這些參數(shù)就稱為props
(屬性)
舉個栗子:
//定義一個組件
class Greeting extends Component{
render() {
return (
<View style={{alignItems:'center'}}>
<Text>Hello {this.props.name} </Text>
</View>
);
};
}
export default class HelloWorld extends Component{
render() {
let pic = {
uri:"https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg"
};
return (
<View style={{alignItems:'center'}}>
<Image source={pic} style={{width: 200, height: 100}} ></Image>
<Greeting name = 'Rex'></Greeting>
<Greeting name = 'zhuxinlei'></Greeting>
<Greeting name = 'ahah'></Greeting>
<Blink name = '哈哈哈哈'></Blink>
</View>
);
}
}
上面栗子中骚露,Greeting組件的 name 就是一個屬性,并在 <Text>Hello {this.props.name} </Text>
組件中使用props屬性集合中name這個屬性恋沃。
如果在定義組件的時候沒有定義name這個屬性冰啃,則 <Text>Hello {this.props.name} </Text>
不會輸出有效的name屬性值。
狀態(tài)
我們使用兩種數(shù)據(jù)來控制一個組件:props
和state
掰茶。props
是在父組件中指定,而且一經(jīng)指定蜜笤,在被指定的組件的生命周期中則不再改變濒蒋。 對于需要改變的數(shù)據(jù),我們需要使用state
把兔。
1.在 constructor 中初始化state
2.然后在需要修改時調(diào)用setState
方法
舉個栗子:
假如我們需要制作一段不停閃爍的文字啊胶。文字內(nèi)容本身在組件創(chuàng)建時就已經(jīng)指定好了,所以文字內(nèi)容應(yīng)該是一個prop
垛贤。而文字的顯示或隱藏的狀態(tài)(快速的顯隱切換就產(chǎn)生了閃爍的效果)則是隨著時間變化的,因此這一狀態(tài)應(yīng)該寫到state
中趣倾。
class Blink extends Component{
constructor(props) {
super(props);
this.state = { showText: true }; //定義一個 showText 狀態(tài)賦值到this.state狀態(tài)中
this.state = { showOtherText: true}; //定義一個 showOtherText 狀態(tài) 賦值到this.state狀態(tài)中聘惦。 (此時this.state 中有兩個狀態(tài))
// 每1000毫秒對showText狀態(tài)做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
this.setState( previousState => {
return {showOtherText: this.state.showText} //這里不能寫showText,因?yàn)槊疤柡?只能拿到previousState或者使用this.state屬性
})
}, 1000);
}
render(){
// 根據(jù)當(dāng)前showText的值決定是否顯示text內(nèi)容
let display = ( (this.state.showText == this.state.showOtherText) && this.state.showText ) ? this.props.name : '';
return(
<Text>{display}</Text>
);
};
}
export default class HelloWorld extends Component{
render() {
let pic = {
uri:"https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg"
};
return (
<View style={{alignItems:'center'}}>
<Image source={pic} style={{width: 200, height: 100}} ></Image>
<Greeting name = 'Rex'></Greeting>
<Greeting name = 'zhuxinlei'></Greeting>
<Greeting name = 'ahah'></Greeting>
<Blink name = '哈哈哈哈'></Blink>
</View>
);
}
}
重點(diǎn):
每次調(diào)用
setState
時,重新執(zhí)行 render 方法重新渲染。這里我們使用定時器來不停調(diào)用setState
善绎,于是組件就會隨著時間變化不停地重新渲染黔漂。
初學(xué)者要點(diǎn)
- 一切界面變化都是
狀態(tài)state變化
-
state
的修改必須通過setState()
方法- this.state.likes = 100; // 這樣的
直接賦值修改無效!
- setState 是一個 merge 合并操作禀酱,只修改指定屬性炬守,不影響其他屬性
- setState 是
異步
操作,修改不會馬上生效
- this.state.likes = 100; // 這樣的
樣式
使用StyleSheet.create
來集中定義組件的樣式
舉個栗子
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
export default class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
);
}
}
//自定義樣式
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
常見的做法是按順序聲明和使用style
屬性剂跟,以借鑒 CSS 中的“層疊”做法(即后聲明的屬性會覆蓋先聲明的同名屬性)减途。
StyleSheet 詳細(xì)說明
高度與寬度
組件的高度和寬度決定了其在屏幕上顯示的尺寸。
舉個例子:指定寬高
export default class HelloWorld extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View>
<View style={{width:50,height:50,backgroundColor: 'red'}}></View>
<View style={{width:100,height:100,backgroundColor: 'skyblue'}}></View>
<View style={{width:100,height:100,backgroundColor: 'blue'}}></View>
</View>
);
}
}
彈性(Flex)寬高
在組件樣式中使用flex
可以使其在可利用的空間中動態(tài)地擴(kuò)張或收縮曹洽。
一般而言我們會使用flex:1
來指定某個組件擴(kuò)張以撐滿所有剩余的空間鳍置。
如果有多個并列的子組件使用了flex:1
,則這些子組件會平分父容器中剩余的空間送淆。如果這些并列的子組件的flex
值不一樣税产,則誰的值更大,誰占據(jù)剩余空間的比例就更大(即占據(jù)剩余空間的比等于并列組件間flex
值的比)偷崩。
// 試試去掉父View中的`flex: 1`,父View不再具有尺寸辟拷,因此子組件也無法再撐開。
// 然后再用`height: 300`來代替父View的`flex: 1`,子組件的寬度為總寬度阐斜,高度組件平分
<View style={{height:300}}>
<View style={{width:50,height:50,backgroundColor: 'red'}}></View>
<View style={{flex: 1,backgroundColor: 'skyblue'}}></View>
<View style={{flex: 1,backgroundColor: 'blue'}}></View>
<View style={{flex: 1,backgroundColor: 'yellow'}}></View>
</View>
使用FlexBox布局
flexDirection
屬性決定主軸的方向(即項(xiàng)目的排列方向)衫冻。
"column-reverse"| "column" | "row" | "row-reverse" ;
[站外圖片上傳中...(image-f13fdc-1539786979198)]
-
row :主軸為水平方向,起點(diǎn)在左端智听。
render() { return ( <View style={{flex: 1,flexDirection: 'row',}}> <View style={{width:50,height:50,backgroundColor:'red'}}></View> <View style={{width:50,height:50,backgroundColor:'blue'}}></View> </View> ); }
-
row-reverse :主軸為水平方向羽杰,起點(diǎn)在右端。
render() { return ( //水平方向,起點(diǎn)在右端 <View style={{flex: 1,flexDirection: 'row-reverse',}}> <View style={{width:50,height:50,backgroundColor:'red'}}></View> <View style={{width:50,height:50,backgroundColor:'blue'}}></View> </View> ); }
-
column-reverse :主軸為垂直方向到推,起點(diǎn)在下沿考赛。
render() { return ( //主軸為垂直方向,起點(diǎn)在最下端 <View style={{flex: 1,flexDirection: 'column-reverse',}}> <View style={{width:50,height:50,backgroundColor:'red'}}></View> <View style={{width:50,height:50,backgroundColor:'blue'}}></View> </View> ); }
- column :主軸為垂直方向,起點(diǎn)在上沿
render() {
return (
//父視圖是column屬性莉测,則子視圖向下排列
<View style={{flex: 1,flexDirection: 'column',}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
</View>
);
}
Justify Content
在組件的 style 中指定justifyContent
可以決定其子元素沿著主軸的排列方式颜骤。子元素是應(yīng)該靠近主軸的起始端還是末尾段分布呢?亦或應(yīng)該均勻分布捣卤?
對應(yīng)的這些可選項(xiàng)有:
flex-start" | "flex-end" | "center" | "space-between" | "space-around"
-
flex-start
: 左對齊
render() {
return (
<View style={{flex: 1,flexDirection: 'row', justifyContent:'flex-start'}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
</View>
);
}
-
flex-end
: 右對齊
render() {
return (
<View style={{flex: 1,flexDirection: 'row', justifyContent:'flex-end'}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
</View>
);
}
-
center
: 居中
render() {
return (
<View style={{flex: 1,flexDirection: 'row', justifyContent:'center'}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
</View>
);
}
-
space-between
: 兩端對齊忍抽,項(xiàng)目之間的間隔都相等
render() {
return (
<View style={{flex: 1,flexDirection: 'row', justifyContent:'space-between'}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
</View>
);
}
-
space-around
:每個項(xiàng)目兩側(cè)的間隔相等。所以董朝,項(xiàng)目之間的間隔比項(xiàng)目與邊框的間隔大一倍
render() {
return (
<View style={{flex: 1,flexDirection: 'row', justifyContent:'space-around'}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
</View>
);
}
Align Items
在組件的 style 中指定alignItems
可以決定其子元素沿著次軸(與主軸垂直的軸鸠项,比如若主軸方向?yàn)?code>row,則次軸方向?yàn)?code>column)的對齊方式子姜。子元素是應(yīng)該靠近次軸的起始端還是末尾段分布呢祟绊?亦或應(yīng)該均勻分布?對應(yīng)的這些可選項(xiàng)有:flex-start
、center
牧抽、flex-end
以及stretch
嘉熊。
"flex-start" | "flex-end" | "center" | "stretch" | "baseline"
注意:要使
stretch
選項(xiàng)生效的話,子元素在次軸方向上不能有固定的尺寸扬舒。以下面的代碼為例:只有將子元素樣式中的width: 50
去掉之后阐肤,alignItems: 'stretch'
才能生效。
-
flex-start
:交叉軸的起點(diǎn)對齊讲坎。 -
flex-end
:交叉軸的終點(diǎn)對齊孕惜。 -
center
:交叉軸的中點(diǎn)對齊。 -
baseline
: 項(xiàng)目的第一行文字的基線對齊衣赶。 -
stretch
(默認(rèn)值):如果項(xiàng)目未設(shè)置高度或設(shè)為auto诊赊,將占滿整個容器的高度。
舉個例子:
render() {
return (
<View style={{
flex: 1,
flexDirection: 'column', //主軸方向
justifyContent:'flex-start', //子元素沿著主軸的對齊方式
alignItems: 'center', //子元素沿著次軸的排列方式-交叉軸的起點(diǎn)對齊
}}>
<View style={{width: 50,height: 50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor: 'blue'}}></View>
<View style={{width:50,height:50,backgroundColor: 'yellow'}}></View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
</View>
);
}
總結(jié):
當(dāng)主軸的方向是 row
橫向時
-
justifyContent
:主軸決定子元素左右的位置府瞄。flex-start"(最左) flex-end(最右)center(居中)space-between( 兩端對齊) 碧磅,space-around (每個項(xiàng)目兩側(cè)的間隔相等) -
alignItems
:次軸 決定子元素上下的位置。 flex-start(最上) flex-end (最下) center(居中)
當(dāng)主軸的方向是 column
縱向時
-
justifyContent
: 主軸決定子元素上下的位置. flex-start"(最上) flex-end(最下)center(居中)space-between( 兩端對齊) -
alignItems
:次軸 決定子元素左右的位置遵馆。flex-start(最左) flex-end (最右) center(居中)
舉個例子:
return (
<View style={{
flex: 1,
flexDirection: 'row', //主軸方向?yàn)闄M向
justifyContent:'flex-start', //子元素沿著主軸的對齊方式,即決定左右位置鲸郊。 左
alignItems: 'center', //子元素沿著次軸的排列方式-交叉軸的起點(diǎn)對齊。 即決定上下位置货邓。中
}}>
<View style={{width: 50,height: 50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor: 'blue'}}></View>
<View style={{width:50,height:50,backgroundColor: 'yellow'}}></View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
</View>
);
}
return (
<View style={{
flex: 1,
flexDirection: 'column', //主軸方向?yàn)榭v向
justifyContent:'flex-start', //子元素沿著主軸的對齊方式 上
alignItems: 'center', //子元素沿著次軸的排列方式-交叉軸的起點(diǎn)對齊 中
}}>
<View style={{width: 50,height: 50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor: 'blue'}}></View>
<View style={{width:50,height:50,backgroundColor: 'yellow'}}></View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
</View>
);
}
處理觸摸事件
直接上代碼:
import React, { Component } from 'react';
import { View, Text,Button,Alert ,AppRegistry,StyleSheet} from 'react-native';
export default class HelloWorld extends Component {
constructor(props) {
super(props);
this.state = {
};
}
//定義一個方法
_onPressButton(){
//提示方法
Alert.alert(
"alert title",
"alert message",
[
{text:'OK', onPress: ()=> console.log("點(diǎn)擊了OK")},
{text:'cancel', onPress: ()=> console.log("點(diǎn)了cancel")}
]
);
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title='pressMe'
></Button>
</View>
<View style={styles.buttonContainer}>
<Button
onPress = {this._onPressButton}
title = 'Press Me'
color='#841584'
></Button>
</View>
<View style={styles.alternativeLayoutbuttonContainer}>
<Button
onPress = {this._onPressButton}
title = 'This looks great!'
></Button>
<Button
onPress = {this._onPressButton}
title = "OK"
color = "#841584"
></Button>
</View>
</View>
);
}
}
//定義樣式
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
buttonContainer:{
margin: 20, //同時設(shè)置四個外邊距
backgroundColor:'yellow'
},
alternativeLayoutbuttonContainer:{
margin:20,
flexDirection: 'row',
justifyContent: 'space-between',
}
})
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
Touchable 系列組件
- 一般來說秆撮,你可以使用TouchableHighlight來制作按鈕或者鏈接。注意此組件的背景會在用戶手指按下時變暗
- TouchableOpacity會在用戶手指按下時降低按鈕的透明度换况,而不會改變背景的顏色职辨。
- 如果你想在處理點(diǎn)擊事件的同時不顯示任何視覺反饋,則需要使用TouchableWithoutFeedback戈二。
某些場景中你可能需要檢測用戶是否進(jìn)行了長按操作舒裤。可以在上面列出的任意組件中使用onLongPress
屬性來實(shí)現(xiàn)觉吭。
舉個例子:
import React, { Component } from 'react';
import { View, Text ,Button,AppRegistry,Alert,Platform,StyleSheet,TouchableHighlight,TouchableOpacity,TouchableNativeFeedback,TouchableWithoutFeedback} from 'react-native';
export default class HelloWorld extends Component {
constructor(props) {
super(props);
this.state = {
};
}
//點(diǎn)擊方法
_onPressButton(){
Alert.alert(
'溫馨提示',
'you tapped the button!',
[
{text:'確定',onPress: () => console.log("點(diǎn)擊了確定") },
{text:'取消', onPress: () => console.log("點(diǎn)擊了取消")},
]
)
}
_onLongPressButton(){
Alert.alert(
'titile',
'you long tapped the button!',
[
{text:'確定',onPress: () => console.log("點(diǎn)擊了確定")},
{text:'取消',onPress: () => console.log("點(diǎn)擊了取消")},
]
)
}
render() {
<View style={styles.container}>
{/* //點(diǎn)擊后高亮 */}
<TouchableHighlight onPress={this._onPressButton} underlayColor='white'>
<View style={styles.button} >
<Text style={styles.buttonText}>TouchableHighlight</Text>
</View>
</TouchableHighlight>
{/* //點(diǎn)擊后透明 */}
<TouchableOpacity onPress={this._onPressButton}>
<View style={styles.button}>
<Text style={styles.buttonText}> TouchableOpacity</Text>
</View>
</TouchableOpacity>
<TouchableNativeFeedback
onPress={this._onPressButton}
backgroundColor={Platform.OS === 'android'? TouchableNativeFeedback.SelectableBackground() : '' }>
<View style={styles.button}>
<Text style={styles.buttonText}> TouchableNativeFeedback </Text>
</View>
</TouchableNativeFeedback>
{/* //點(diǎn)擊后無反饋 */}
<TouchableWithoutFeedback onPress={this._onPressButton}>
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableWithoutFeedback</Text>
</View>
</TouchableWithoutFeedback>
{/* //高亮長按 */}
<TouchableHighlight onPress={this._onPressButton} onLongPress={this._onLongPressButton} underlayColor='white'>
<View style={styles.button}>
<Text style={styles.buttonText}>touchable with long press</Text>
</View>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
paddingTop: 60,
alignItems: 'center',
},
button:{
marginBottom: 30,
width: 260,
alignItems: 'center',
backgroundColor: '#2196F3',
borderRadius:5
},
buttonText: {
padding:20,
color: 'white'
}
})
AppRegistry.registerComponent('HelloWorld',() => HelloWorld)
StyleSheet 詳細(xì)說明
var styles = StyleSheet.create({
base: {width:38,height:38},
background:{backgroundColor:'#222'}
active:{borderWidth:2,borderColor:'#00ff00'}
});
Text style={styles.base} /
Text style={{styles.base, styles.background}} /
Text style={{styles.base, this.state.active && styles.active}} /
backfaceVisibility:visible|hidden;屬性定義當(dāng)元素不面向屏幕時是否可見
backgroundColor:背景色
transform
transformMatrix
定位
position:定位:相對定位(absolute)腾供,絕對定位(relative) 默認(rèn)情況下使用的是相對定位
top:上
bottom:下
left:左
right:右
圖像變換
scaleX :水平方向縮放
scaleY :垂直方向縮放
rotation :旋轉(zhuǎn)
translateX :水平方向平移
translateY :水平方向平移
陰影
shadowColor
shadowOffset
shadowOpacity
shadowRadius
圖片相關(guān)屬性
resizeMode:enum('cover','contain','stretch') contain是指無論如何圖片都包含在指定區(qū)域內(nèi),假設(shè)設(shè)置的寬度高度比圖片大鲜滩,則圖片居中顯示伴鳖,否則,圖片等比縮小顯示
overflow:enum('visible','hidden')
tintColor:著色徙硅,rgb字符串類型
opacity:透明度
字體相關(guān)屬性
color:字體顏色
fontFamily:字體族
fontSize:字體大小
fontStyle:字體樣式,正常,傾斜榜聂,值為enum('normal','italic')
fontWeight:字體粗細(xì),值為enum('normal','bold','100','200'...,'900')
letterSpacing:字符間隔
lineHeight:行高
textAlign:字體對齊方式,值為enum('auto','left','right','center','justify')
textDecorationColor:貌似沒效果嗓蘑,修飾的線的顏色
textDecorationLine:貌似沒效果峻汉,字體修飾贴汪,上劃線,下劃線休吠,刪除線,無修飾业簿,值為enum("none",'underline','line-through','underline line-through')
textDecorationStyle:enum("solid",'double','dotted','dashed')貌似沒效果瘤礁,修飾的線的類型
writingDirection:enum("auto",'ltr','rtl')不知道什么屬性,寫作方向梅尤?從左到右柜思?從右到左?
邊框相關(guān)
borderStyle:邊框樣式
borderWidth:所有邊框?qū)挾?
borderTopWidth:頂部邊框?qū)挾?
borderBottomWidth:底部邊框?qū)挾?
borderLeftWidth:左邊邊框?qū)挾?
borderRightWidth:右邊框?qū)挾?
borderColor:邊框顏色
borderTopColor:頂部邊框顏色
borderBottomColor:底部邊框顏色
borderLeftColor:左邊邊框顏色
borderRightColor:右邊邊框顏色
邊框圓角
borderRadius
borderBottomLeftRadius
borderBottomRightRadius
borderTopLeftRadius
borderTopRightRadius
Flex布局相關(guān)
flex:number
flexDirection: enum('row','column','row-reverse','column-reverse') 屬性決定主軸的方向(即項(xiàng)目的排列方向)巷燥。
flexWrap:enum('wrap','nowrap','wrap-reverse') 默認(rèn)情況下赡盘,項(xiàng)目都排在一條線(又稱"軸線")上。flex-wrap屬性定義缰揪,如果一條軸線排不下陨享,如何換行。
alignItems:enum('flex-start','flex-end','center','stretch') 屬性定義項(xiàng)目在交叉軸上如何對齊钝腺。
alignSelf:enum('auto','flex-start','flex-end','center','stretch') 屬性允許單個項(xiàng)目有與其他項(xiàng)目不一樣的對齊方式抛姑,可覆蓋
justifyContent:enum('flex-start','flex-end','center','space-between','space-around') 屬性定義了項(xiàng)目在主軸上的對齊方式。
Flex 布局教程:語法篇 Flex 布局教程:實(shí)例篇
寬高
width
height
外邊距:
marginTop:上
marginBottom:下
marginLeft:左
marginRight:右
margin:相當(dāng)于同時設(shè)置四個
marginVertical:相當(dāng)于同時設(shè)置marginTop和marginBottom
marginHorizontal:相當(dāng)于同時設(shè)置marginLeft和marginRight
內(nèi)邊距
paddingTop:上
paddingBottom:下
paddingLeft:左
paddingRight:右
padding:相當(dāng)于同時設(shè)置四個
paddingVertical:相當(dāng)于同時設(shè)置paddingTop和paddingBottom
paddingHorizontal:相當(dāng)于同時設(shè)置paddingLeft和paddingRight