组件具体的API参考官网: React Native API
1. View,Text, StyleSheet
// View类似Div,但是不能直接写内容
// 样式没有class,只有style,通过 StyleSheet进行创建
// 样式没有px,宽高,字体等数字都是没有单位的,会自动转化,安卓dp,苹果pt
// flex布局中 flexDirection默认是column,跟web不同, alignItems默认是stretch,不是flex-start
// flex 只接受一个属性
import React, {Component} from 'react';
import {View, Text, StyleSheet} from 'react-native';
class App extends Component {
constructor(props) {
super(props);
this.state = {
titleList: ['View', 'Text', 'StyleSheet'],
};
}
render() {
const {titleList} = this.state;
return (
<View style={styles.titleWrap}>
{titleList.map(title => (
<View style={styles.titleItem} key={title}>
{/*react的语法,style是个变量*/}
<Text style={styles.title}>{title}</Text>
{/*样式的数组写法,写在后边的同一样式属性,会进行覆盖,下面就是color覆盖成红色了*/}
<Text style={[styles.title, styles.mgt, styles.titleBehind]}>
{title}
</Text>
</View>
))}
</View>
);
}
}
const styles = StyleSheet.create({
titleBehind: {
color: 'red',
},
title: {
color: '#fff',
fontSize: 14,
},
titleWrap: {
flexDirection: 'row',
height: 100,
},
titleItem: {
flex: 1,
marginLeft: 4,
marginRight: 4,
backgroundColor: '#ffae00',
justifyContent: 'center',
alignItems: 'center',
},
mgt: {
marginTop: 10,
},
});
export default App;
2. React Navigation 官网: 直通车
2-1.基础堆栈导航 createStackNavigator
为你的应用程序提供一种在每个新屏幕放置在堆栈顶部的屏幕之间转换的方法。
默认情况下,stack navigator 被配置为具有熟悉的iOS和Android外观:新屏幕从iOS右侧滑入,从Android底部淡入。 在iOS上,stack navigator 也可以配置为屏幕从底部滑入的模式样式
安装依赖配置: 基础依赖安装
// 另外还需要安装 react-navigation-stack
yarn add react-navigation-stack
import { createStackNavigator } from 'react-navigation-stack';
createStackNavigator(RouteConfigs, StackNavigatorConfig);
//参数
RouteConfigs
createStackNavigator({
//路由的页面的key,用于navigation.navigate跳转时候传参
Profile: {
screen: ProfileScreen, //当前的页面对应的组件
path: 'people/:name', //一般用于web和外部链接,app里面基本不用
//导航的配置,也可以在具体页面里面用static navigationOptions配置
// 可以直接是json,也可以是函数返回json
navigationOptions: ({ navigation }) => ({
title: `这是标题`,
}),
},
});
StackNavigatorConfig的属性 具体参考 StackNavigatorConfig
// tab/index.js 使用示例createStackNavigator+createBottomTabNavigator
import {createBottomTabNavigator} from 'react-navigation-tabs';
import {createStackNavigator} from 'react-navigation-stack';
import Home from './Home';
import Mine from './Mine';
import HomeInnerDetail from '../User';
import {Image} from 'react-native';
import React from 'react';
const HomeWrap = createStackNavigator({
Home: {
screen: Home,
navigationOptions: {
header: null, //去掉导航
},
},
// 这里有个需求,就是进入到详情页后,tabbar是不想展示的,然而下面的tabBarVisible是无用的
HomeInnerDetail: {
screen: HomeInnerDetail,
navigationOptions: {
headerTitle: 'Home详情',
tabBarVisible: false, //这个设置是没有用的,因为HomeInnerDetail的父级是HomeWrap,不是createBottomTabNavigator
},
},
});
// 可以通过这种方式进行判断,因为HomeWrap的父级是TabBar,tabBarVisible属性是有用的
// 还有种办法就是控制页面的结构,详情页HomeInnerDetail放到和TabBar同级的createStackNavigator里面 具体可以了解
// https://reactnavigation.org/docs/zh-Hans/navigation-options-resolution.html
// 阐述了navigationOptions的注意点
HomeWrap.navigationOptions = ({navigation}) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible,
};
};
// 这是构建tabBar导航的方法,跟createStackNavigator大同小异,属性有点差异,公共属性一样
const TabBar = createBottomTabNavigator(
{
Home: {
screen: HomeWrap,
navigationOptions: {
tabBarLabel: '首页',
tabBarIcon: () => (
<Image
style={{width: 20, height: 20}}
source={{
uri:
'https://c-ssl.duitang.com/uploads/blog/201510/26/20151026153614_8EnAS.thumb.700_0.jpeg',
}}
/>
),
},
},
Mine: {
screen: Mine,
},
},
{
tabBarOptions: {
activeTintColor: '#e91e63',
showIcon: true,
},
},
);
export default TabBar;
2-2. createBottomTabNavigator
// 依赖的安装
yarn add react-navigation-tabs
// 使用方式
import { createBottomTabNavigator } from 'react-navigation-tabs';
createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig);
RouteConfigs的和createStackNavigator一样
BottomTabNavigatorConfig的属性 : 直通车
常用属性:
initialRouteName //第一次加载时初始选项卡路由的 routeName
navigationOptions //导航器本身的导航选项,用于配置父导航器(注意是父级)
defaultNavigationOptions // 用于屏幕的默认导航选项,是当前导航
lazy
// 默认值: true. 如果false,则所有选项卡都将立即呈现。
// 如果为true,则仅在第一次使选项卡处于活动状态时才会显示这些选项卡
tabBarComponent //覆盖用作标签栏的组件 自定义
tabBarOptions // tabbar的属性设置,样式,颜色等,具体参考上面的直通车
页面内部的 navigationOptions: 直通车
常用属性:
title // 用作headerTitle和tabBarLabel的后备的通用标题
tabBarVisible // true或false用于显示或隐藏标签栏,如果未设置,则默认为true
tabBarIcon
// 图标,给定{focused:boolean, horizontal:boolean, tintColor:string}的函数返回React.Node
tabBarLabel
// 显示在选项卡栏中的选项卡的标题字符串
// 或给定{focused:boolean, tintColor:string}的函数将返回React.Node,以显示在选项卡栏中
tabBarButtonComponent //React组件,它包装图标和标签并实现onPress
// 使用实例演示
// tab/index.js
import {createBottomTabNavigator} from 'react-navigation-tabs';
import {createStackNavigator} from 'react-navigation-stack';
import Home from './Home';
import Mine from './Mine';
import HomeInnerDetail from '../User';
import {Image} from 'react-native';
import React from 'react';
const HomeWrap = createStackNavigator({
Home: {
screen: Home,
navigationOptions: {
header: null, //去掉导航
},
},
// 这里有个需求,就是进入到详情页后,tabbar是不想展示的,然而下面的tabBarVisible是无用的
HomeInnerDetail: {
screen: HomeInnerDetail,
navigationOptions: {
headerTitle: 'Home详情',
tabBarVisible: false, //这个设置是没有用的,因为HomeInnerDetail的父级是HomeWrap,不是createBottomTabNavigator
},
},
});
// 可以通过这种方式进行判断,因为HomeWrap的父级是TabBar,tabBarVisible属性是有用的
// 还有种办法就是控制页面的结构,详情页HomeInnerDetail放到和TabBar同级的createStackNavigator里面 具体可以了解
// https://reactnavigation.org/docs/zh-Hans/navigation-options-resolution.html
// 阐述了navigationOptions的注意点
HomeWrap.navigationOptions = ({navigation}) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible,
};
};
// 这是构建tabBar导航的方法,跟createStackNavigator大同小异,属性有点差异,公共属性一样
const TabBar = createBottomTabNavigator(
{
Home: {
screen: HomeWrap,
//这个设置的是当前的页面,就是Home,而Home是createBottomTabNavigator,所以有tabBarLabel属性
navigationOptions: {
tabBarLabel: '首页',
},
},
Mine: {
screen: Mine,
},
},
{
tabBarOptions: {
activeTintColor: '#e91e63',
showIcon: true,
},
// 导航器本身的导航选项,用于配置父导航器
// 父级是AppNavigator,是createStackNavigator,所以有headerStyle,headerTitleStyle这些属性
navigationOptions: {
title: '父级的标题',
headerStyle: {
backgroundColor: '#ffae00',
},
headerTitleStyle: {
fontSize: 20,
color: '#fff',
fontWeight: 'bold',
},
},
// 用于屏幕的默认导航选项 比如没有图片的时候,给个默认的图片
// 设置的是当前的,当前的是createBottomTabNavigator
defaultNavigationOptions: {
tabBarIcon: () => (
<Image
style={{width: 20, height: 20}}
source={{
uri:
'https://c-ssl.duitang.com/uploads/blog/201510/26/20151026153614_8EnAS.thumb.700_0.jpeg',
}}
/>
),
},
},
);
export default TabBar;
// Route.js 最终的父级,用于App Render
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import TabBar from './tab';
import Detail from './Detail';
import DrawerInfo from './drawer/DrawerInfo';
import DrawerHome from './drawer/DrawerHome';
import {createDrawerNavigator} from 'react-navigation-drawer';
const AppNavigator = createStackNavigator({
Tab: {
screen: TabBar, //上面的tab/index.js的引用地方
},
Detail: {
screen: Detail,
},
});
//下面是个抽屉
const Drawer = createDrawerNavigator(
{
DrawerInfo: {
screen: DrawerInfo,
},
AppNavigator: {
screen: AppNavigator,
},
},
{
initialRouteName: 'AppNavigator',
contentComponent: DrawerHome, //内容的自定义组件
},
);
export default createAppContainer(Drawer);
2-3 createDrawerNavigator 抽屉导航 直通车
// 依赖
yarn add react-navigation-drawer
// 使用
import { createDrawerNavigator } from 'react-navigation-drawer';
createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig)
RouteConfigs可以参照createStackNavigator
DrawerNavigatorConfig属性: 直通车
// 常用属性
drawerBackgroundColor //抽屉背景色
drawerPosition // left 或 right
drawerWidth // 数字或返回抽屉宽度的函数,宽度
contentComponent //用于呈现抽屉内容 (例如, 导航项) 的组件。 接收抽屉的navigation和drawerOpenProgress。 默认为 DrawerItems
contentOptions // 配置抽屉内容 [DrawerItems]
// 具体可以参考
// https://reactnavigation.org/docs/zh-Hans/drawer-navigator.html#draweritems-%E7%9A%84-contentoptions
navigationOptions // 导航器本身的导航选项,用于配置父导航器
defaultNavigationOptions //用于屏幕的默认导航选项
initialRouteName // 第一次加载时初始选项卡路由的 routeName
// 注意点
如果抽屉导航器嵌套在另一个提供某个UI的导航器中,例如选项卡导航器或堆栈导航器,则抽屉将从这些导航器的UI下呈现。[你会看不到] ,抽屉会出现在标签栏的下方并位于堆栈的标题下方。
你将需要将抽屉导航器作为抽屉应该呈现在其UI之上的任何导航器的父级
// 例子1 最外层
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import TabBar from './tab';
import Detail from './Detail';
import DrawerInfo from './drawer/DrawerInfo';
import DrawerHome from './drawer/DrawerHome';
import {createDrawerNavigator} from 'react-navigation-drawer';
const AppNavigator = createStackNavigator({
Tab: {
screen: TabBar,
},
Detail: {
screen: Detail,
},
});
// 这里的createDrawerNavigator形成的Drawer就是AppNavigator的父级
// 这里是放在最外层,所有页面AppNavigator和DrawerInfo都会有抽屉
const Drawer = createDrawerNavigator(
{
DrawerInfo: {
screen: DrawerInfo,
},
AppNavigator: {
screen: AppNavigator,
},
},
{
initialRouteName: 'AppNavigator',
contentComponent: DrawerHome,
},
);
export default createAppContainer(Drawer);
--------------------------------------------------------------------------
// 例子2 在tab的父级
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import TabBar from './tab';
import Detail from './Detail';
import DrawerInfo from './drawer/DrawerInfo';
import DrawerHome from './drawer/DrawerHome';
import {createDrawerNavigator} from 'react-navigation-drawer';
// 这里放在tab的父级,不是最外层
const Drawer = createDrawerNavigator(
{
Tab: {
screen: TabBar,
},
DrawerInfo: {
screen: DrawerInfo,
},
},
{
initialRouteName: 'Tab',
navigationOptions: {
header: null,
},
contentComponent: DrawerHome,
},
);
const AppNavigator = createStackNavigator({
Drawer: {
screen: Drawer,
},
Detail: {
screen: Detail, //这个页面就没有抽屉了
},
});
export default createAppContainer(AppNavigator);
常用页面内导航属性 navigationOptions:
title // 用作headerTitle和tabBarLabel的后备的通用标题
drawerLabel // 字符串,React 元素或给定{ focused: boolean, tintColor: string }返回一个 React.Node 的函数,用于在标签栏中显示。 未定义时,使用title
drawerIcon // 图标 React 元素或给定{ focused: boolean, tintColor: string }的函数返回一个 React.Node,用于在标签栏中显示
2-4. createMaterialTopTabNavigator 一般用于顶部tab 直通车
// 依赖
yarn add react-navigation-tabs
// 使用
import { createMaterialTopTabNavigator } from 'react-navigation-tabs';
createMaterialTopTabNavigator(RouteConfigs, TabNavigatorConfig);
RouteConfigs 同上
TabNavigatorConfig 常用属性: 具体参考 直通车
initialRouteName // 第一次加载时初始选项卡路由的 routeName
navigationOptions // 导航器本身的导航选项,用于配置父导航器
defaultNavigationOptions // 用于屏幕的默认导航选项
tabBarPosition // 位置 标签栏的位置, 可以是 'top' 或 'bottom'。默认值是top
swipeEnabled // 是否允许在标签页之间进行滑动
lazy // 默认值 false. 如果true,则仅在使选项卡处于活动状态或快速扫视时才显示它们
tabBarComponent // 可选,覆盖用作标签栏的组件, 自定义
tabBarOptions // 图标,样式,文字等具体的tabbar的样式
tabBarOptions 具体参考 直通车
// 实例
const MineTab = createMaterialTopTabNavigator(
{
Info: Info,
Money: Money,
},
{
lazy: true,
// 这个是不是自定义才有效果
tabBarOptions: {
activeTintColor: '#ffae00',
upperCaseLabel: false,
labelStyle: {fontWeight: 'bold'},
showIcon: true,
},
// 自定义
tabBarComponent: () => (
<View style={{height: 60, backgroundColor: '#999'}}>
<Text>自定义</Text>
</View>
),
},
);
下面的是自定义的效果,tab整个被自定义了,下面是tabbar每个tab对应的具体内容
下面是非自定义的:
2-5. 导航器作为组件
// 有时需要嵌套一个被包装的导航器到组件中。 这在导航器只占用屏幕一部分空间的情况下非常有用。
// 为了将子导航器连接到导航树中,需要父导航器的navigation属性
// 在这种情况下,Mine不是导航器,但是它将导航器作为其输出的一部分。
// 如果此导航器呈现空白,则将<View>更改为<View style = {{flex:1}}>
// 为了将MineTab 连接到导航树中,我们将其router分配给包装组件。 这使得Mine导航感知,它告诉父导航器向下传递导航对象。
// 由于Mine的router被子导航器的router覆盖,因此子导航器将接收所需的navigation
import React, {Component} from 'react';
import {Text, Image, View} from 'react-native';
import {createMaterialTopTabNavigator} from 'react-navigation-tabs';
import Info from './mine/Info';
import Money from './mine/Money';
const MineTab = createMaterialTopTabNavigator(
{
Info: Info,
Money: Money,
},
{
lazy: true,
tabBarOptions: {
activeTintColor: '#ffae00',
upperCaseLabel: false,
labelStyle: {fontWeight: 'bold'},
showIcon: true,
},
tabBarComponent: () => (
<View style={{height: 60, backgroundColor: '#999'}}>
<Text>自定义</Text>
</View>
),
},
);
export class Mine extends Component {
static navigationOptions = {
tabBarLabel: '个人中心',
tabBarIcon: () => (
<Image
style={{width: 20, height: 20}}
source={{
uri:
'https://c-ssl.duitang.com/uploads/blog/201510/26/20151026153614_8EnAS.thumb.700_0.jpeg',
}}
/>
),
};
render() {
return (
<View style={{flex: 1}}>
<View>
<Text>这是头部tab页面</Text>
</View>
{/* 这是个导航器.传递navigation */}
<MineTab navigation={this.props.navigation} />
</View>
);
}
}
Mine.router = MineTab.router; //赋值router
export default Mine;