# api集合
# props state
大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props(属性)。
我们使用两种数据来控制一个组件:props和state。 props 是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用 state 。
# style
按照 JS 的语法要求使用了驼峰命名法,例如将background-color改为backgroundColor。 实际开发中组件的样式会越来越复杂,我们建议使用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',
},
});
# flex
如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的。
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class FlexDimensionsBasics extends Component {
render() {
return (
// 试试去掉父View中的`flex: 1`。
// 则父View不再具有尺寸,因此子组件也无法再撑开。
// 然后再用`height: 300`来代替父View的`flex: 1`试试看?
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}} />
<View style={{flex: 2, backgroundColor: 'skyblue'}} />
<View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>
);
}
}
# flexDirection
在组件的style中指定flexDirection可以决定布局的主轴。子元素是应该沿着水平轴(row)方向排列,还是沿着竖直轴(column)方向排列呢?默认值是竖直轴(column)方向。
# justifyContent
在组件的 style 中指定justifyContent可以决定其子元素沿着主轴的排列方式。子元素是应该靠近主轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start、center、flex-end、space-around、space-between以及space-evenly。
# alignItems
可以决定其子元素沿着次轴(与主轴垂直的轴,比如若主轴方向为row,则次轴方向为column)的排列方式。子元素是应该靠近次轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start、center、flex-end以及stretch。
注意
要使stretch选项生效的话,子元素在次轴方向上不能有固定的尺寸。以下面的代码为例:只有将子元素样式中的width: 50去掉之后,alignItems: 'stretch'才能生效。
# width height
width和height。React Native 中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点。
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class FixedDimensionsBasics extends Component {
render() {
return (
<View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
<View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>
);
}
}
# Animated
Animated旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用简单的start/stop方法来控制动画按顺序执行。 Animated仅封装了四个可以动画化的组件:View、Text、Image和ScrollView,不过可以使用Animated.createAnimatedComponent()来封装自己的组件。下面是一个在加载时带有淡入动画效果的视图:
import React from 'react';
import { Animated, Text, View } from 'react-native';
class FadeInView extends React.Component {
state = {
fadeAnim: new Animated.Value(0), // 透明度初始值设为0
}
componentDidMount() {
Animated.timing( // 随时间变化而执行动画
this.state.fadeAnim, // 动画中的变量值
{
toValue: 1, // 透明度最终变为1,即完全不透明
duration: 10000, // 让动画持续一段时间
}
).start(); // 开始执行动画
}
render() {
let { fadeAnim } = this.state;
return (
<Animated.View // 使用专门的可动画化的View组件
style={{
...this.props.style,
opacity: fadeAnim, // 将透明度指定为动画变量值
}}
>
{this.props.children}
</Animated.View>
);
}
}
// 然后你就可以在组件中像使用`View`那样去使用`FadeInView`了
export default class App extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
<Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
</FadeInView>
</View>
)
}
}
我们来分解一下这个过程。在FadeInView的构造函数里,我们创建了一个名为fadeAnim的Animated.Value,并放在state中。而View的透明度是和这个值绑定的。
组件加载时,透明度首先设为 0。然后一个easing动画开始改变fadeAnim值,同时会导致所有与其相关联的值(本例中是透明度)也逐帧更新,最终和fadeAnim一样变为1。
这一过程经过特别优化,执行效率会远高于反复调用setState和多次重渲染。
因为这一过程是纯声明式的,因此还有进一步优化的空间,比如我们可以把这些声明的配置序列化后发送到一个高优先级的线程上运行。
# 配置动画
动画拥有非常灵活的配置项。自定义的或预定义的 easing 函数、延迟、持续时间、衰减系数、弹性常数等都可以在对应类型的动画中进行配置。
Animated.timing(this.state.xPosition, {
toValue: 100,
easing: Easing.back(),
duration: 2000
}).start();
# 组合动画
多个动画可以通过parallel(同时执行)、sequence(顺序执行)、stagger和delay来组合使用。它们中的每一个都接受一个要执行的动画数组,并且自动在适当的时候调用start/stop。
Animated.sequence([
// decay, then spring to start and twirl
Animated.decay(position, {
// coast to a stop
velocity: { x: gestureState.vx, y: gestureState.vy }, // velocity from gesture release
deceleration: 0.997
}),
Animated.parallel([
// after decay, in parallel:
Animated.spring(position, {
toValue: { x: 0, y: 0 } // return to start
}),
Animated.timing(twirl, {
// and twirl
toValue: 360
})
])
]).start(); // start the sequence group
默认情况下,如果任何一个动画被停止或中断了,组内所有其它的动画也会被停止。Parallel 有一个stopTogether属性,如果设置为false,可以禁用自动停止。
在Animated文档的组合动画一节中列出了所有的组合方法。