入门
Props属性
大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为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属性值。
状态
我们使用两种数据来控制一个组件:props
和state
。props
是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用state
。
1.在 constructor 中初始化state
2.然后在需要修改时调用setState
方法
举个栗子:
假如我们需要制作一段不停闪烁的文字。文字内容本身在组件创建时就已经指定好了,所以文字内容应该是一个prop
。而文字的显示或隐藏的状态(快速的显隐切换就产生了闪烁的效果)则是随着时间变化的,因此这一状态应该写到state
中。
class Blink extends Component{
constructor(props) {
super(props);
this.state = { showText: true }; //定义一个 showText 状态赋值到this.state状态中
this.state = { showOtherText: true}; //定义一个 showOtherText 状态 赋值到this.state状态中。 (此时this.state 中有两个状态)
// 每1000毫秒对showText状态做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
this.setState( previousState => {
return {showOtherText: this.state.showText} //这里不能写showText,因为冒号后 只能拿到previousState或者使用this.state属性
})
}, 1000);
}
render(){
// 根据当前showText的值决定是否显示text内容
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>
);
}
}
重点:
每次调用
setState
时,重新执行 render 方法重新渲染。这里我们使用定时器来不停调用setState
,于是组件就会随着时间变化不停地重新渲染。
初学者要点
- 一切界面变化都是
状态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 详细说明
高度与宽度
组件的高度和宽度决定了其在屏幕上显示的尺寸。
举个例子:指定宽高
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
可以使其在可利用的空间中动态地扩张或收缩。
一般而言我们会使用flex:1
来指定某个组件扩张以撑满所有剩余的空间。
如果有多个并列的子组件使用了flex:1
,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex
值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间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
属性决定主轴的方向(即项目的排列方向)。
"column-reverse"| "column" | "row" | "row-reverse" ;
[站外图片上传中...(image-f13fdc-1539786979198)]
-
row :主轴为水平方向,起点在左端。
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 :主轴为水平方向,起点在右端。
render() { return ( //水平方向,起点在右端 <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 :主轴为垂直方向,起点在下沿。
render() { return ( //主轴为垂直方向,起点在最下端 <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 :主轴为垂直方向,起点在上沿
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>
);
}
屏幕快照 2018-10-17 22.15.01.png
Justify Content
在组件的 style 中指定justifyContent
可以决定其子元素沿着主轴的排列方式。子元素是应该靠近主轴的起始端还是末尾段分布呢?亦或应该均匀分布?
对应的这些可选项有:
flex-start" | "flex-end" | "center" | "space-between" | "space-around"
img
-
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>
);
}
屏幕快照 2018-10-17 22.32.13.png
-
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>
);
}
屏幕快照 2018-10-17 22.38.09.png
-
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>
);
}
[图片上传中...(屏幕快照 2018-10-17 22.42.07.png-75b45f-1539787624115-0)]
-
space-between
: 两端对齐,项目之间的间隔都相等
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>
);
}
屏幕快照 2018-10-17 22.42.07.png
-
space-around
:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
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>
);
}
屏幕快照 2018-10-17 22.43.22.png
Align Items
在组件的 style 中指定alignItems
可以决定其子元素沿着次轴(与主轴垂直的轴,比如若主轴方向为row
,则次轴方向为column
)的对齐方式。子元素是应该靠近次轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start
、center
、flex-end
以及stretch
。
"flex-start" | "flex-end" | "center" | "stretch" | "baseline"
图片注意:要使
stretch
选项生效的话,子元素在次轴方向上不能有固定的尺寸。以下面的代码为例:只有将子元素样式中的width: 50
去掉之后,alignItems: 'stretch'
才能生效。
-
flex-start
:交叉轴的起点对齐。 -
flex-end
:交叉轴的终点对齐。 -
center
:交叉轴的中点对齐。 -
baseline
: 项目的第一行文字的基线对齐。 -
stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
举个例子:
render() {
return (
<View style={{
flex: 1,
flexDirection: 'column', //主轴方向
justifyContent:'flex-start', //子元素沿着主轴的对齐方式
alignItems: 'center', //子元素沿着次轴的排列方式-交叉轴的起点对齐
}}>
<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>
);
}
屏幕快照 2018-10-18 22.30.36.png
总结:
当主轴的方向是 row
横向时
-
justifyContent
:主轴决定子元素左右的位置。flex-start"(最左) flex-end(最右)center(居中)space-between( 两端对齐) ,space-around (每个项目两侧的间隔相等) -
alignItems
:次轴 决定子元素上下的位置。 flex-start(最上) flex-end (最下) center(居中)
当主轴的方向是 column
纵向时
-
justifyContent
: 主轴决定子元素上下的位置. flex-start"(最上) flex-end(最下)center(居中)space-between( 两端对齐) -
alignItems
:次轴 决定子元素左右的位置。flex-start(最左) flex-end (最右) center(居中)
举个例子:
return (
<View style={{
flex: 1,
flexDirection: 'row', //主轴方向为横向
justifyContent:'flex-start', //子元素沿着主轴的对齐方式,即决定左右位置。 左
alignItems: 'center', //子元素沿着次轴的排列方式-交叉轴的起点对齐。 即决定上下位置。中
}}>
<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>
);
}
屏幕快照 2018-10-18 22.37.58.png
return (
<View style={{
flex: 1,
flexDirection: 'column', //主轴方向为纵向
justifyContent:'flex-start', //子元素沿着主轴的对齐方式 上
alignItems: 'center', //子元素沿着次轴的排列方式-交叉轴的起点对齐 中
}}>
<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>
);
}
屏幕快照 2018-10-18 22.42.16.png
处理触摸事件
直接上代码:
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("点击了OK")},
{text:'cancel', onPress: ()=> console.log("点了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, //同时设置四个外边距
backgroundColor:'yellow'
},
alternativeLayoutbuttonContainer:{
margin:20,
flexDirection: 'row',
justifyContent: 'space-between',
}
})
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
Touchable 系列组件
- 一般来说,你可以使用TouchableHighlight来制作按钮或者链接。注意此组件的背景会在用户手指按下时变暗
- TouchableOpacity会在用户手指按下时降低按钮的透明度,而不会改变背景的颜色。
- 如果你想在处理点击事件的同时不显示任何视觉反馈,则需要使用TouchableWithoutFeedback。
某些场景中你可能需要检测用户是否进行了长按操作。可以在上面列出的任意组件中使用onLongPress
属性来实现。
举个例子:
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 = {
};
}
//点击方法
_onPressButton(){
Alert.alert(
'温馨提示',
'you tapped the button!',
[
{text:'确定',onPress: () => console.log("点击了确定") },
{text:'取消', onPress: () => console.log("点击了取消")},
]
)
}
_onLongPressButton(){
Alert.alert(
'titile',
'you long tapped the button!',
[
{text:'确定',onPress: () => console.log("点击了确定")},
{text:'取消',onPress: () => console.log("点击了取消")},
]
)
}
render() {
<View style={styles.container}>
{/* //点击后高亮 */}
<TouchableHighlight onPress={this._onPressButton} underlayColor='white'>
<View style={styles.button} >
<Text style={styles.buttonText}>TouchableHighlight</Text>
</View>
</TouchableHighlight>
{/* //点击后透明 */}
<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>
{/* //点击后无反馈 */}
<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)
屏幕快照 2018-10-19 11.20.42.png
StyleSheet 详细说明
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;属性定义当元素不面向屏幕时是否可见
backgroundColor:背景色
transform
transformMatrix
定位
position:定位:相对定位(absolute),绝对定位(relative) 默认情况下使用的是相对定位
top:上
bottom:下
left:左
right:右
图像变换
scaleX :水平方向缩放
scaleY :垂直方向缩放
rotation :旋转
translateX :水平方向平移
translateY :水平方向平移
阴影
shadowColor
shadowOffset
shadowOpacity
shadowRadius
图片相关属性
resizeMode:enum('cover','contain','stretch') contain是指无论如何图片都包含在指定区域内,假设设置的宽度高度比图片大,则图片居中显示,否则,图片等比缩小显示
overflow:enum('visible','hidden')
tintColor:着色,rgb字符串类型
opacity:透明度
字体相关属性
color:字体颜色
fontFamily:字体族
fontSize:字体大小
fontStyle:字体样式,正常,倾斜,值为enum('normal','italic')
fontWeight:字体粗细,值为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')不知道什么属性,写作方向?从左到右?从右到左?
边框相关
borderStyle:边框样式
borderWidth:所有边框宽度
borderTopWidth:顶部边框宽度
borderBottomWidth:底部边框宽度
borderLeftWidth:左边边框宽度
borderRightWidth:右边框宽度
borderColor:边框颜色
borderTopColor:顶部边框颜色
borderBottomColor:底部边框颜色
borderLeftColor:左边边框颜色
borderRightColor:右边边框颜色
边框圆角
borderRadius
borderBottomLeftRadius
borderBottomRightRadius
borderTopLeftRadius
borderTopRightRadius
Flex布局相关
flex:number
flexDirection: enum('row','column','row-reverse','column-reverse') 属性决定主轴的方向(即项目的排列方向)。
flexWrap:enum('wrap','nowrap','wrap-reverse') 默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
alignItems:enum('flex-start','flex-end','center','stretch') 属性定义项目在交叉轴上如何对齐。
alignSelf:enum('auto','flex-start','flex-end','center','stretch') 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖
justifyContent:enum('flex-start','flex-end','center','space-between','space-around') 属性定义了项目在主轴上的对齐方式。
宽高
width
height
外边距:
marginTop:上
marginBottom:下
marginLeft:左
marginRight:右
margin:相当于同时设置四个
marginVertical:相当于同时设置marginTop和marginBottom
marginHorizontal:相当于同时设置marginLeft和marginRight
内边距
paddingTop:上
paddingBottom:下
paddingLeft:左
paddingRight:右
padding:相当于同时设置四个
paddingVertical:相当于同时设置paddingTop和paddingBottom
paddingHorizontal:相当于同时设置paddingLeft和paddingRight
网友评论