React Native 组件主要分为三种: 基础组件、交互组件、列表组件
基础组件
基础组件包含:
- View:用于搭建用户组件的最基础组件
- Text:用于显示文本的内容
- Image:显示图片内容的组件
- TextInput:文本显示框
- ScrollView:可滚动的容器视图
- StyleSheet:提供类似CSS样式表的样式抽象层
View
作为创建 UI 时最基础的组件,View 是一个支持 Flexbox 布局、样式、一些触摸处理、和一些无障碍功能的容器,并且它可以放到其它的视图里,也可以有任意多个任意类型的子视图。
class ViewColoredBoxesWithText extends Component {
render() {
return (
<View
style={{
flexDirection: "row",
height: 100,
padding: 20
}}
>
<View style={{ backgroundColor: "blue", flex: 0.3 }} />
<View style={{ backgroundColor: "red", flex: 0.5 }} />
<Text>Hello World!</Text>
</View>
);
}
}
用于 View 响应属性 (例如, onResponderMove), 合成触摸事件采用以下的格式:
nativeEvent
- changedTouches - 从上一次事件以来的触摸事件数组。
- identifier - 触摸事件的 ID。
- locationX - 触摸事件相对元素位置的 X 坐标。
- locationY - 触摸事件相对元素位置的 Y 坐标。
- pageX - 触摸事件相对根元素位置的 X 坐标。
- pageY - 触摸事件相对根元素位置的 Y 坐标。
- target - 接收触摸事件的元素 ID.
- timestamp - 触摸事件的时间标记,用来计算速度.
- touches - 屏幕上所有当前触摸事件的数组.
绑定View的触摸响应事件
Text
一个用于显示文本的React组件,并且它也支持嵌套、样式,以及触摸处理。
import React, { Component } from 'react';
import { Text, StyleSheet } from 'react-native';
export default class TextInANest extends Component {
constructor(props) {
super(props);
this.state = {
titleText: "Bird's Nest",
bodyText: 'This is not really a bird nest.'
};
}
render() {
return (
<Text style={styles.baseText}>
<Text style={styles.titleText} onPress={this.onPressTitle}>
{this.state.titleText}{'\n'}{'\n'}
</Text>
<Text numberOfLines={5}>
{this.state.bodyText}
</Text>
</Text>
);
}
}
const styles = StyleSheet.create({
baseText: {
fontFamily: 'Cochin',
},
titleText: {
fontSize: 20,
fontWeight: 'bold',
},
});
这个例子使用了styles 样式分离的方式来制作,显示Text的相关属性。
Image
TextInput
TextInput是一个允许用户在应用中通过键盘输入文本的基本组件。本组件的属性提供了多种特性的配置,譬如自动完成、自动大小写、占位文字,以及多种不同的键盘类型(如纯数字键盘)等等。
import React, { Component } from 'react';
import { TextInput } from 'react-native';
export default class UselessTextInput extends Component {
constructor(props) {
super(props);
this.state = { text: 'Useless Placeholder' };
}
render() {
return (
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
);
}
}
多行文本框
import React, { Component } from 'react';
import { View, TextInput } from 'react-native';
class UselessTextInput extends Component {
render() {
return (
<TextInput
{...this.props} // 将父组件传递来的所有props传递给TextInput;比如下面的multiline和numberOfLines
editable = {true}
maxLength = {40}
/>
);
}
}
export default class UselessTextInputMultiline extends Component {
constructor(props) {
super(props);
this.state = {
text: 'Useless Multiline Placeholder',
};
}
// 你可以试着输入一种颜色,比如red,那么这个red就会作用到View的背景色样式上
render() {
return (
<View style={{
backgroundColor: this.state.text,
borderBottomColor: '#000000',
borderBottomWidth: 1 }}
>
<UselessTextInput
multiline = {true}
numberOfLines = {4}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
</View>
);
}
}
ScrollView
一个封装了平台的ScrollView(滚动视图)的组件,同时还集成了触摸锁定的“响应者”系统。
记住ScrollView必须有一个确定的高度才能正常工作,因为它实际上所做的就是将一系列不确定高度的子组件装进一个确定高度的容器(通过滚动操作)。要给ScrollView一个确定的高度的话,要么直接给它设置高度(不建议),要么确定所有的父容器都有确定的高度。一般来说我们会给ScrollView设置flex: 1以使其自动填充父容器的空余空间,但前提条件是所有的父容器本身也设置了flex或者指定了高度,否则就会导致无法正常滚动,你可以使用元素查看器来查找具体哪一层高度不正确。
ScrollView内部的其他响应者尚无法阻止ScrollView本身成为响应者。
ScrollView和FlatList应该如何选择?ScrollView会简单粗暴地把所有子元素一次性全部渲染出来。其原理浅显易懂,使用上自然也最简单。然而这样简单的渲染逻辑自然带来了性能上的不足。想象一下你有一个特别长的列表需要显示,可能有好几屏的高度。创建和渲染那些屏幕以外的JS组件和原生视图,显然对于渲染性能和内存占用都是一种极大的拖累和浪费。
这就是为什么我们还有专门的FlatList组件。FlatList会惰性渲染子元素,只在它们将要出现在屏幕中时开始渲染。这种惰性渲染逻辑要复杂很多,因而API在使用上也更为繁琐。除非你要渲染的数据特别少,否则你都应该尽量使用FlatList,哪怕它们用起来更麻烦。
此外FlatList还可以方便地渲染行间分隔线,支持多列布局,无限滚动加载等等。
交互空间
Button
import { Button } from 'react-native';
...
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
Picker
本组件可以在iOS和Android上渲染原生的选择器(Picker)。
<Picker
selectedValue={this.state.language}
style={{ height: 50, width: 100 }}
onValueChange={(itemValue, itemIndex) => this.setState({language: itemValue})}>
<Picker.Item label="Java" value="java" />
<Picker.Item label="JavaScript" value="js" />
</Picker>
slider
用于选择一个范围值的组件。
switch
跨平台通用的“开关”组件。
这些平台在不同的平台上的定义方式不一样,所以出现的是跨平台的相应组件。
注意这是一个“受控组件”(controlled component)。你必须使用onValueChange回调来更新value属性以响应用户的操作。如果不更新value属性,组件只会按一开始给定的value值来渲染且保持不变,看上去就像完全点不动。
@keyword checkbox @keyword toggle @keyword 单选 @keyword 多选
列表视图
Flatlist
高性能的简单列表组件,支持下面这些常用的功能:
完全跨平台。
支持水平布局模式。
行组件显示或隐藏时可配置回调事件。
支持单独的头部组件。
支持单独的尾部组件。
支持自定义行间分隔线。
支持下拉刷新。
支持上拉加载。
支持跳转到指定行(ScrollToIndex)。
如果需要分组/类/区(section),请使用
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
Sectionlist
高性能的分组(section)列表组件,支持下面这些常用的功能:
完全跨平台。
行组件显示或隐藏时可配置回调事件。
支持单独的头部组件。
支持单独的尾部组件。
支持自定义行间分隔线。
支持分组的头部组件。
支持分组的分隔线。
支持多种数据源结构
支持下拉刷新。
支持上拉加载。
如果你的列表不需要分组(section),那么可以使用结构更简单的
简单的例子:
// Example 1 (Homogeneous Rendering)
<SectionList
renderItem={({ item, index, section }) => <Text key={index}>{item}</Text>}
renderSectionHeader={({ section: { title } }) => (
<Text style={{ fontWeight: "bold" }}>{title}</Text>
)}
sections={[
{ title: "Title1", data: ["item1", "item2"] },
{ title: "Title2", data: ["item3", "item4"] },
{ title: "Title3", data: ["item5", "item6"] }
]}
keyExtractor={(item, index) => item + index}
/>