【iOS开发】(五)react Native路由和导航20240421-22

【iOS开发】(五)react Native 路由和导航Navigation 20240421

在(一)(二)中我们 Reactnative搭建了开发环境、学习了 基础语法、状态管理,JSX、组件、状态和生命周期以及样式布局等。
在(三)(四) React native 我们介绍了 RN中的基础组件和第三方组件。

今天我们来学习基础语法中最后一块重要的内容,路由和导航。

目录标题

      • 〇 简介路由和导航
          • 路由(Routing)
          • React Navigation
          • 设置导航
          • React Navigation 学习前提条件
            • 1 React Native Express (第1至4节)
            • 2 React的主要概念
            • 3 React Hooks
            • 4 React Context (高级)
      • 一 简介
          • 1 安装组件库
          • 2 安装依赖
          • 3 链接
      • 二 基础组件
        • 1 添加头部组件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1c1d340b6d024a1bb5247832a80b2c07.png)
        • 2 添加导航容器
      • 三 几种基本导航类型
          • 1. 堆栈导航(Stack Navigation)
          • 2. 底部标签导航(Bottom Tab Navigation)
          • 3. 抽屉导航(Drawer Navigation)
          • 4. Material顶部标签导航(Material Top Tab Navigation)

〇 简介路由和导航

路由和导航是Web和移动应用中至关重要的概念,它们用于指导用户在应用的不同部分和页面之间移动。

路由(Routing)

路由通常指的是确定一个用户请求应该如何被处理的过程。在Web应用中,路由涉及到解析URL,并根据这个URL映射到相应的页面或视图上。对于复杂的前端Web应用,通常会使用客户端路由来在不同视图间切换而无需从服务器重新加载页面。

在React Native中,路由和导航指的是用户在 不同屏幕或视图(通常称为“路由”) 之间移动的方式。由于React Native是一个用于构建移动应用的框架,所以它的路由和导航是专门为触摸界面设计的,能够处理各种手势操作和过渡动画。

React Navigation

在React Native中,最流行的路由和导航库是React Navigation。它提供了多种导航方法:

  • 堆栈导航(Stack Navigator):
    管理一系列屏幕,用户可以在屏幕间前进和后退。
    使用push和pop操作来管理屏幕堆栈。
  • 底部标签导航(Bottom Tab Navigator):
    在屏幕底部显示标签栏,用户可以通过点击不同的标签来切换视图。
  • 抽屉导航(Drawer Navigator):
    提供从屏幕边缘滑入的导航菜单,类似于抽屉式的交互模式。
  • 顶部标签导航(Material Top Tabs Navigator):
    在屏幕顶部显示标签栏,用户可以通过滑动或点击标签来切换视图。
    这种风格常见于Android应用,使用了Material Design规范。
设置导航

要在React Native应用中设置导航,通常需要以下步骤:

安装React Navigation库及其依赖。
创建导航器(例如堆栈导航器或标签导航器)并定义路由。
使用NavigationContainer组件包裹应用的根组件。

学习本部分内容,建议查漏补缺:

React Navigation 学习前提条件

在开始学习React Navigation之前,确保你已经熟悉以下关键技术和概念。如果你已经有JavaScript、React和React Native的基础,你将能够快速上手React Navigation。如果你对这些还不够熟悉,建议先学习以下内容:

1 React Native Express (第1至4节)
  • 一个快速入门React Native的学习平台。
  • 包含设置开发环境、理解基础组件、状态管理、样式和布局等核心概念。
  • 推荐给刚开始接触React Native的开发者。
2 React的主要概念
  • React官方文档的主要概念部分提供了全面的介绍。
  • 学习内容包括JSX、组件、props、state、事件处理等基础知识。
  • 强烈建议理解组件生命周期和组件间的数据流。
3 React Hooks
  • React Hooks是React 16.8引入的新特性,允许在函数组件中使用state和其他React特性。
  • 重要的Hooks包括useState, useEffect, useContext等。
  • React官方文档提供了详细的Hooks介绍和使用指南。
4 React Context (高级)
  • Context API允许组件跨层级直接共享状态,而不是通过props链式传递。
  • 对于主题、用户认证、应用偏好等跨组件共享的数据非常有用。
  • 需要注意的是,不当使用可能会导致组件难以维护,因此建议在真正需要全局状态管理时才使用。

在了解了这些基础知识后,你将更好地准备学习React Navigation,并在你的React Native应用中实现复杂的导航逻辑。

一 简介

在React Native中,路由和导航是管理应用中页面或视图之间切换的关键技术。要实现这一功能,通常会使用第三方库,因为React Native本身并不包括内建的导航系统。React Navigation:流行的路由和导航库的组件。。
这是React Native中最流行的导航库组件之一。
它支持堆栈导航、标签导航、抽屉导航等多种导航方式。
React Navigation易于使用,并且高度可定制,支持屏幕转换动画、传递参数到不同屏幕等功能。

1 安装组件库
npm install @react-navigation/native
2 安装依赖
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

这个命令会安装以下库:

  • react-native-reanimated:提供更为强大和灵活的动画库,用于创建复杂的动画和交互。
  • react-native-gesture-handler:一个用来处理触摸手势的库,它优化了触摸响应的性能和体验。
  • react-native-screens:利用原生平台的视图容器来优化内存使用和性能
  • react-native-safe-area-context:提供了一个安全区域的上下文,可以用来适配屏幕的安全区域,避免界面元素与设备特定的屏幕部位(如刘海、圆角等)冲突。
  • @react-native-community/masked-view:一个实现遮罩视图的库,可以用来在视图上创建遮罩效果。

确保React Native环境已经配置好,并且这些库与React Native版本兼容。在安装这些库后,可能需要链接某些库(如果你的React Native版本低于0.60),并对Android和iOS项目进行必要的配置,以确保一切正常工作。

3 链接
  • RN0.60 后安卓环境自动链接路由(Android 无需任何操作 )
  • ios下需要手动链接路由
npx pod-install ios

二 基础组件

1 添加头部组件 在这里插入图片描述

首先,需要在应用的最顶部导入react-native-gesture-handler。这是因为react-native-gesture-handler提供了一个可以更精细地控制手势和触摸事件的系统,这对于实现流畅的导航动画和用户体验至关重要。

导入这个模块的正确位置是在应用的入口文件中,通常是index.js或App.js。这需要放在任何其他代码之前,因为它要尽可能早地在应用中设置好手势处理的环境。

这里是一个示例代码:

// index.js 或 App.js
import 'react-native-gesture-handler'; // 这行代码要放在最上面
// 其他的导入和代码...
2 添加导航容器

导航容器(NavigationContainer)是一个组件,它管理着你的应用状态和导航树结构,它必须包裹在你的应用外层,这样React Navigation库才能正常工作。它通常也是放在index.js或App.js文件中。

这里是如何包裹你的应用:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import MyStack from './MyStack'; // 假设你有一个堆栈导航器设置在另一个文件中const App = () => {return (<NavigationContainer><MyStack /></NavigationContainer>);
};export default App;

在上面的例子中,MyStack是一个假设的组件,它表示你的应用的堆栈导航。当然,你可以根据需要替换为你自己的导航结构,无论是底部标签导航、抽屉导航还是其他类型的导航。

确保你的整个应用都被NavigationContainer包裹着,这样无论你在应用中的哪个部分,React Navigation都能访问当前的导航状态。这是启用导航功能的必备结构。

三 几种基本导航类型

详细介绍React Navigation中的几种基本导航类型:堆栈导航(Stack Navigation)、底部标签导航(Bottom Tab Navigation)、抽屉导航(Drawer Navigation)以及Material顶部标签导航(Material Top Tab Navigation)。

1. 堆栈导航(Stack Navigation)

堆栈导航允许应用维护一个页面的堆栈,类似于导航控制器。新的页面可以放到堆栈的顶部,并且可以返回到之前的页面。

主要特性

  • 页面间的无缝过渡。
  • 可以自定义过渡动画。
  • 支持页面传参。
 npm install @react-navigation/stack
// 引入所需的React Native组件
import {Text, // 用于显示文本StyleSheet, // 用于定义组件的样式View, // 用作容器,可以包裹其他组件Button, // 显示一个可点击的按钮TouchableOpacity, // 一个包装器,可以包含其他组件,并使它们可触摸Alert, // 提供弹出警告对话框的功能
} from 'react-native';
import React, {Component} from 'react'; // 引入React以及类组件的基类Component
import {createStackNavigator} from '@react-navigation/stack'; // 引入创建堆栈导航器的函数
import { NavigationContainer } from '@react-navigation/native'; // 引入包裹导航器的容器组件// 定义HomeScreen组件,表示主屏幕
function HomeScreen(prop) {// 展示基本信息,并提供一个按钮用于跳转到NewsScreen页面return (<View style={styles.container}><Text style={styles.text}>HomeScreen</Text><Buttontitle={'跳到新闻页面'}onPress={() => prop.navigation.navigate('News')} // 使用navigate方法跳转到指定的路由(页面)/></View>);
}// 定义NewsScreen组件,表示新闻页面
function NewsScreen(prop) {// 类似HomeScreen,展示基本信息,并提供一个按钮用于返回HomeScreen页面return (<View style={styles.container}><Text style={styles.text}>NewsScreen</Text><Buttontitle={'跳转到Home页面'}onPress={() => prop.navigation.navigate('Home')} // 使用navigate方法跳转回HomeScreen/></View>);
}const Stack = createStackNavigator(); // 创建一个堆栈导航器// 定义Index类组件,作为应用的主组件
export default class Index extends Component {render() {// 使用NavigationContainer包裹导航器,确保导航状态正确管理return (<NavigationContainer> <Stack.Navigator  initialRouteName='News'   screenOptions={{headerShown:true}}><Stack.Screenname="Home" // 路由名称component={HomeScreen} // 与此路由关联的组件options={{title: '首页', // 设置屏幕顶部导航条的标题headerStyle: {backgroundColor: 'tomato', // 自定义标题栏背景颜色},headerRight: () => (// 添加一个按钮在标题栏右侧<TouchableOpacity onPress={() => Alert.alert('Hello')}><Text style={{ marginRight: 15 }}>Hello</Text></TouchableOpacity>),}}/><Stack.Screen name="News" component={NewsScreen} /></Stack.Navigator></NavigationContainer>);}
}// 定义组件的样式
const styles = StyleSheet.create({container: {flex: 1, // flex: 1 使组件填满父容器的全部空间justifyContent: 'center', // 垂直居中显示alignItems: 'center', // 水平居中显示},text: {fontSize: 40, // 设置字体大小},
});

简介版

import { Text, StyleSheet, View, Button } from 'react-native';
import React, { Component } from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';function HomeScreen(props) {return (<View style={styles.container}><Text style={styles.text}>Home Screen</Text><Button title="跳转到新闻"onPress={() => props.navigation.navigate('News')}/></View>);
}function NewsScreen(props) {return (<View style={styles.container}><Text style={styles.text}>News Screen</Text><Buttontitle="跳转到home主页"onPress={() => props.navigation.navigate('Home')}/></View>);
}const Stack = createStackNavigator();export default class Index extends Component {render() {return (<NavigationContainer><Stack.Navigator><Stack.Screenname='Home'component={HomeScreen}/><Stack.Screenname='News'component={NewsScreen}/></Stack.Navigator></NavigationContainer>);}
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: "center",alignItems: "center"},text: {fontSize: 40,}
});

关于navigation对象和navigate方法:
navigation是React Navigation传递给每个屏幕组件的对象,它包含了控制导航的多种方法。
navigate方法用于触发导航到应用中的其他屏幕,通常接受目标屏幕的名字作为参数,也可以传递附加数据。
<Stack.Screen />组件:
<Stack.Screen />是一个React Navigation的组件,用于在堆栈导航器中注册一个新的屏幕。
name属性定义了屏幕的标识符,用于编程时引用和导航到这个屏幕。
component属性指定当导航到这个屏幕时应该渲染哪个组件。

此代码中,

  <Text style={[styles.text]}>Home Screen</Text><Button title={'跳转到新闻'}/*** prop:prop 是 React 中组件接收的参数,它包含了传递给组件的所有属性。在使用 React Navigation 时,所有通过导航器(Navigator)加载的组件会自动接收一个 navigation 属性。这个属性包含了一系列方法,用来编程式地控制导航行为,如跳转、后退等。prop.navigation:navigation 是 React Navigation 传递给每个屏幕组件的对象,包含了多种导航相关的方法和属性。通过这个对象,你可以控制应用的导航状态,执行如跳转、返回、参数传递等操作。navigate:navigate 是 navigation 对象中的一个方法,用于触发导航到应用中的其他屏幕。这个方法接受一个参数,通常是目标屏幕的名字(在代码中为 'News'),这个名字是在你设置导航器时定义的屏幕名。navigate 方法还可以接收第二个可选参数,用于传递数据到目标屏幕。这可以使你在不同的页面间传递需要的信息。简单来说,当你在 HomeScreen 组件中点击按钮时,onPress 事件会触发 prop.navigation.navigate('News') 调用,这会告诉 React Navigation 切换视图到 NewsScreen 组件。*///此处写一个具体的事件 onPress ,里面是回调函数   ()=>  // 可以通过传过来的参数 prop来跳转//prop 里面有 onPress={() => props.navigation.navigate('News')}/>

在这里插入图片描述

2. 底部标签导航(Bottom Tab Navigation)

底部标签导航在屏幕底部显示多个标签,用户可以切换不同的视图或页面。

主要特性
适合快速切换不同视图的应用。
可定制标签样式和动画。

npm install @react-navigation/bottom-tabs

我们要使用icon图标 所以也装一下


react-native-vector-icons/Ionicons 是一个在 React Native 应用中广泛使用的库,它提供了一套丰富的矢量图标,可以轻松地在移动应用中使用。这些图标是基于矢量技术的,意味着它们在不同的屏幕分辨率和尺寸上都可以保持清晰。Ionicons 是这个库中的一个图标集,它包括了一系列优雅的、常用的图标,适用于多种用户界面设计。

主要特点
跨平台支持:这些图标可以在 iOS 和 Android 平台上使用,且看起来一致。
自定义和扩展性:你可以轻松地调整图标的大小、颜色和样式,使其适应你的应用设计。
丰富的图标资源:Ionicons 包括了数百个图标,涵盖了大多数常见的 UI 设计需求。

在这里插入图片描述

/* eslint-disable react/no-unstable-nested-components */
import {Text, StyleSheet, View, Button} from 'react-native';
import React, {Component} from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import { NavigationContainer } from '@react-navigation/native';function HomeScreen(props) {  // 更正 prop 为 props,这是常规的参数命名约定return (<View style={styles.container}><Text style={styles.text}>HomeScreen</Text><Buttontitle="跳到新闻页面"  // 保持引号的一致性onPress={() => props.navigation.navigate('News')}/></View>);
}function NewsScreen(props) {  // 更正 prop 为 propsreturn (<View style={styles.container}><Text style={styles.text}>NewsScreen</Text><Buttontitle="跳转到Home页面"  // 保持引号的一致性onPress={() => props.navigation.navigate('Home')}/></View>);
}const Tab = createBottomTabNavigator();export default class Index extends Component {render() {return (<NavigationContainer><Tab.NavigatorscreenOptions={({route}) => ({tabBarIcon: ({focused, color, size}) => {let iconName;if (route.name === 'Home') {iconName = focused ? 'add-circle' : 'add-circle-outline';} else if (route.name === 'News') {iconName = focused ? 'person' : 'person-outline';}return <Icon name={iconName} size={size} color={color} />;},tabBarActiveTintColor: 'tomato',  // 将 tabBarOptions 的设置迁移到 screenOptions 中tabBarInactiveTintColor: 'gray',})}><Tab.Screen name="Home" component={HomeScreen} /><Tab.Screen name="News" component={NewsScreen} /></Tab.Navigator></NavigationContainer>);}
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 40,},
});
/* eslint-disable react/no-unstable-nested-components */
import {Text, StyleSheet, View, Button} from 'react-native';
import React, {Component} from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import { NavigationContainer } from '@react-navigation/native';function HomeScreen(props) {  // 更正 prop 为 props,这是常规的参数命名约定return (<View style={styles.container}><Text style={styles.text}>HomeScreen</Text><Buttontitle="跳到新闻页面"  // 保持引号的一致性onPress={() => props.navigation.navigate('News')}/></View>);
}function NewsScreen(props) {  // 更正 prop 为 propsreturn (<View style={styles.container}><Text style={styles.text}>NewsScreen</Text><Buttontitle="跳转到Home页面"  // 保持引号的一致性onPress={() => props.navigation.navigate('Home')}/></View>);
}const Tab = createBottomTabNavigator();export default class Index extends Component {render() {return (<NavigationContainer><Tab.NavigatorscreenOptions={({route}) => ({tabBarIcon: ({focused, color, size}) => {let iconName;if (route.name === 'Home') {iconName = focused ? 'add-circle' : 'add-circle-outline';} else if (route.name === 'News') {iconName = focused ? 'person' : 'person-outline';}return <Icon name={iconName} size={size} color={color} />;},tabBarActiveTintColor: 'tomato',  // 将 tabBarOptions 的设置迁移到 screenOptions 中tabBarInactiveTintColor: 'gray',})}><Tab.Screen name="Home" component={HomeScreen} /><Tab.Screen name="News" component={NewsScreen} /></Tab.Navigator></NavigationContainer>);}
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 40,},
});
3. 抽屉导航(Drawer Navigation)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

抽屉导航通过滑动或点击图标来展开一个从页面边缘滑出的导航面板。

主要特性
可以包含用户账户信息、链接列表等。
支持手势操作。

Uncaught Error [Reanimated] Failed to create a worklet. See https://docs.swmansion.com/react-native-reanimated/docsguides/troubleshooting#failed-to-create-a-workletfor more details. Source

看起来您遇到的错误与react-native-reanimated的工作单元(worklet)有关。这个问题通常发生在Reanimated的工作单元无法正确初始化时。下面是一些可能的解决步骤:

解决步骤
确认Reanimated插件:
确保babel.config.js中正确添加了react-native-reanimated/plugin。这一步是必要的,因为Reanimated 2 需要这个插件来正确转换工作单元代码。配置应如下所示:

module.exports = {presets: ['module:metro-react-native-babel-preset'],plugins: ['react-native-reanimated/plugin'],
};

如果已经配置了插件,试着再次清理缓存:

yarn start --reset-cache

在项目目录内执行:

npx react-native start --reset-cache

在这里插入图片描述

import React, { Component } from 'react';
import { Text, StyleSheet, View, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import Icon from 'react-native-vector-icons/Ionicons';function HomeScreen({ navigation }) {return (<View style={styles.container}><Text style={styles.text}>HomeScreen</Text><Buttontitle="Open Drawer"onPress={() => navigation.openDrawer()}/><Buttontitle="Toggle Drawer"onPress={() => navigation.toggleDrawer()}/></View>);
}function NewsScreen({ navigation }) {return (<View style={styles.container}><Text style={styles.text}>NewsScreen</Text><Buttontitle="Open Drawer"onPress={() => navigation.openDrawer()}/><Buttontitle="跳转到Home页面"onPress={() => navigation.navigate('Home')}/></View>);
}const Drawer = createDrawerNavigator();function Index() {return (<Drawer.NavigatorscreenOptions={{drawerStyle: {backgroundColor: '#c6cbef',width: 180,},drawerPosition: 'right',drawerType: 'slide',drawerActiveTintColor: 'red',drawerItemStyle: {marginVertical: 20,},}}><Drawer.Screenoptions={{title: '首页',drawerIcon: ({ focused, color, size }) => (<Icon name={focused ? 'home' : 'home-outline'} size={size} color={color} />),}}name="Home"component={HomeScreen}/><Drawer.Screenoptions={{title: '新闻',drawerIcon: ({ focused, color, size }) => (<Icon name={focused ? 'person' : 'person-outline'} size={size} color={color} />),}}name="News"component={NewsScreen}/></Drawer.Navigator>);
}export default function App() {return (<NavigationContainer><Index /></NavigationContainer>);
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 40,},
});

下面带注释

/* eslint-disable react/no-unstable-nested-components */
import {Text, StyleSheet, View, Button} from 'react-native';
import React, {Component} from 'react';
import {createDrawerNavigator} from '@react-navigation/drawer';
import Icon from 'react-native-vector-icons/Ionicons';
import { NavigationContainer } from '@react-navigation/native';/*** drawer编译错误[Reanimated] `valueUnpacker` is not a worklet, js engine: hermes* 的解决办法 参考文章https://blog.csdn.net/lxyoucan/article/details/121851577* 第一步* 修改配置文件babel.config.js(在项目根目录)并增加plugins: ['react-native-reanimated/plugin'],* 示例:* module.exports = {*   presets: [‘module:metro-react-native-babel-preset’],*   plugins: [‘react-native-reanimated/plugin’],* };* 第二步* cmd命令行进入项目根目录,然后执行* yarn start --reset-cache* 清除缓存* 以上执行完毕之后* 关掉模拟器重新执行项目即可正常*/function HomeScreen(prop) {// 跳转方法prop.navigation.navigate参数是路由名称也就是Stack.Screen namereturn (<View style={[styles.container]}><Text style={[styles.text]}>HomeScreen</Text><Buttontitle={'Open Drawer'}onPress={() => prop.navigation.openDrawer()}/><Buttontitle={'Toggle Drawer'}onPress={() => prop.navigation.toggleDrawer()}/></View>);
}function NewsScreen(prop) {return (<View style={[styles.container]}><Text style={[styles.text]}>NewsScreen</Text><Buttontitle={'Open Drawer'}onPress={() => prop.navigation.openDrawer()}/><Buttontitle={'跳转到Home页面'}onPress={() => prop.navigation.navigate('Home')}/></View>);
}const Drawer = createDrawerNavigator();export default class Index extends Component {render() {return (<NavigationContainer><Drawer.Navigator// 这里新版本和教程有变化,新版本属性写在screenOptions里screenOptions={{drawerStyle: {backgroundColor: '#c6cbef',width: 180,},drawerPosition: 'right', // 控制菜单从左left或者右right弹出drawerType: 'slide', // 菜单的滑动形式drawerActiveTintColor: 'red', // 当前激活的菜单颜色// 设置菜单项的样式drawerItemStyle: {marginVertical: 20,},}}><Drawer.Screenoptions={{title: '首页', // 自定义当前项的标题drawerIcon: ({focused, color, size}) => {let iconName = '';iconName = focused ? 'home' : 'home-outline';return <Icon name={iconName} size={size} color={color} />;},}}name="Home"component={HomeScreen}/><Drawer.Screenoptions={{title: '新闻', // 自定义当前项的标题drawerIcon: ({focused, color, size}) => {let iconName = '';iconName = focused ? 'person' : 'person-outline';return <Icon name={iconName} size={size} color={color} />;},}}name="News"component={NewsScreen}/></Drawer.Navigator></NavigationContainer>);}
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 40,},
});
4. Material顶部标签导航(Material Top Tab Navigation)

使用Material Design指南来实现顶部标签的滑动切换界面。

主要特性
支持滑动操作切换标签。
可定制动画和样式。

import {Text, StyleSheet, View} from 'react-native';
import React, {Component} from 'react';
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import { NavigationContainer } from '@react-navigation/native';
import PagerView from 'react-native-pager-view';function OrderunpayScreen() {return (<View style={[styles.container]}><Text style={[styles.text]}>待付款</Text></View>);
}function OrderPaidScreen() {return (<View style={[styles.container]}><Text style={[styles.text]}>待发货</Text></View>);
}function OrderSentScreen() {return (<View style={[styles.container]}><Text style={[styles.text]}>待收货</Text></View>);
}function OrderFinishScreen() {return (<View style={[styles.container]}><Text style={[styles.text]}>待评价</Text></View>);
}const MTab = createMaterialTopTabNavigator();export default class index extends Component {render() {// tabBarPosition 导航条的位置top|bottom默认是topreturn (<NavigationContainer><MTab.NavigatortabBarPosition="bottom"screenOptions={{// tabBar的整体样式tabBarStyle: {borderWidth: 1,borderColor: 'grey',},// 标签样式tabBarLabelStyle: {fontSize: 20,},tabBarActiveTintColor: 'red', // 当前标签页标签激活时的颜色tabBarInactiveTintColor: '#666', // 当前标签页标签未激活时的颜色tabBarShowIcon: true, //是否显示图标}}><MTab.Screenname="OrderUnpay"component={OrderunpayScreen}options={{title: '待付款',tabBarIcon: ({focused, color}) => {return <Icon name="hammer-outline" color={color} size={20} />;},}}/><MTab.Screenname="OrderPaid"component={OrderPaidScreen}options={{title: '待发货',tabBarIcon: ({focused, color}) => {return (<Iconname="arrow-redo-circle-outline"color={color}size={20}/>);},}}/><MTab.Screenname="OrderSent"component={OrderSentScreen}options={{title: '待收货',tabBarIcon: ({focused, color}) => {return <Icon name="arrow-redo-outline" color={color} size={20} />;},}}/><MTab.Screenname="OrderFinish"component={OrderFinishScreen}options={{title: '待评价',tabBarIcon: ({focused, color}) => {return (<Iconname="chatbubble-ellipses-outline"color={color}size={20}/>);},}}/></MTab.Navigator></NavigationContainer>);}
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 40,},
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/2514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB 数据类型

MATLAB 数据类型 MATLAB 不需要任何类型声明或维度语句。每当 MATLAB 遇到一个新的变量名&#xff0c;它就创建变量并分配适当的内存空间。 如果变量已经存在&#xff0c;那么MATLAB将用新内容替换原始内容&#xff0c;并在必要时分配新的存储空间。 例如&#xff0c; Tota…

Vue3中使用无缝滚动插件vue3-seamless-scroll

官网&#xff1a;https://www.npmjs.com/package/vue-seamless-scroll 1、实现效果文字描述&#xff1a; 表格中的列数据进行横向无缝滚动&#xff0c;某一列进行筛选的时候&#xff0c;重新请求后端的数据&#xff0c;进行刷新 2、安装&#xff1a;npm i vue3-seamless-scrol…

小程序 rich-text 解析富文本 图片过大时如何自适应?

在微信小程序中&#xff0c;用rich-text 解析后端返回的数据&#xff0c;当图片尺寸太大时&#xff0c;会溢出屏幕&#xff0c;导致横向出现滚动 查看富文本代码 图片是用 <img 标签&#xff0c;所以写个正则匹配一下图片标签&#xff0c;手动加上样式即可 // content 为后…

Python 面向对象——5.多态

本章学习链接如下&#xff1a; Python 面向对象——1.基本概念 Python 面向对象——2.类与对象实例属性补充解释&#xff0c;self的作用等 Python 面向对象——3.实例方法&#xff0c;类方法与静态方法 Python 面向对象——4.继承 1.基本概念 多态是面向对象编程&#x…

贪吃蛇(C语言版)

在我们学习完C语言 和单链表知识点后 我们开始写个贪吃蛇的代码 目标&#xff1a;使用C语言在Windows环境的控制台模拟实现经典小游戏贪吃蛇 贪吃蛇代码实现的基本功能&#xff1a; 地图的绘制 蛇、食物的创建 蛇的状态&#xff08;正常 撞墙 撞到自己 正常退出&#xf…

Python蜘蛛侠

目录 写在前面 蜘蛛侠 编写代码 代码分析 更多精彩 写在后面 写在前面 本期小编给大家推荐一个酷酷的Python蜘蛛侠&#xff0c;一起来看看叭~ 蜘蛛侠 蜘蛛侠&#xff08;Spider-Man&#xff09;是美国漫威漫画宇宙中的一位标志性人物&#xff0c;由传奇创作者斯坦李与艺…

探索ChatGPT在提高人脸识别与软性生物识准确性的表现与可解释性

概述 从GPT-1到GPT-3&#xff0c;OpenAI的模型不断进步&#xff0c;推动了自然语言处理技术的发展。这些模型在处理语言任务方面展现出了强大的能力&#xff0c;包括文本生成、翻译、问答等。 然而&#xff0c;当涉及到面部识别和生物特征估计等任务时&#xff0c;这些基于文…

设计模式-00 设计模式简介之几大原则

设计模式-00 设计模式简介之几大原则 本专栏主要分析自己学习设计模式相关的浅解&#xff0c;并运用modern cpp 来是实现&#xff0c;描述相关设计模式。 通过编写代码&#xff0c;深入理解设计模式精髓&#xff0c;并且很好的帮助自己掌握设计模式&#xff0c;顺便巩固自己的c…

用于车载T-BOX汽车级的RA8900CE

用于车载T-BOX等高精度计时的汽车级时钟模块RTC:RA8900CE.车载实时时钟芯片RA8900CE内置32.768Khz的晶体&#xff0c;实现年、月、日、星期、小时、分钟和秒精准计时。RA8900CE满足AEC-Q200认证&#xff0c;内置温补功能&#xff0c;保证实时时钟的稳定可靠&#xff0c;功耗低至…

【Linux】解决ubuntu20.04版本插入无线网卡没有wifi显示【无线网卡Realtek 8811cu】

ubuntu为Realtek 8811cu安装驱动&#xff0c;解决wifi连接问题 1、确认无线网卡的型号-Realtek 8810cu2、下载并配置驱动 一句话总结&#xff1a;先确定网卡的型号&#xff0c;然后根据网卡的型号区寻找对应的驱动下载&#xff0c;下载完成之后在ubuntu系统中进行编译&#xff…

HTTP慢连接攻击的原理和防范措施

随着互联网的快速发展&#xff0c;网络安全问题日益凸显&#xff0c;网络攻击事件频繁发生。其中&#xff0c;HTTP慢速攻击作为一种隐蔽且高效的攻击方式&#xff0c;近年来逐渐出现的越来越多。 为了防范这些网络攻击&#xff0c;我们需要先了解这些攻击情况&#xff0c;这样…

【笔试】03

FLOPS FLOPS 是 Floating Point Operations Per Second 的缩写&#xff0c;意为每秒浮点运算次数。它是衡量计算机性能的指标&#xff0c;特别是用于衡量计算机每秒能够执行多少浮点运算。在高性能计算领域&#xff0c;FLOPS 被广泛用来评估超级计算机、CPU、GPU 和其他处理器…

2024年区块链链游即将迎来大爆发

随着区块链技术的不断发展和成熟&#xff0c;其应用领域也在不断扩展。其中&#xff0c;区块链链游&#xff08;Blockchain Games&#xff09;作为区块链技术在游戏行业中的应用&#xff0c;备受关注。2024年&#xff0c;区块链链游行业即将迎来爆发&#xff0c;这一趋势不容忽…

Windows10如何关闭Edge浏览器的Copilot

在Windows10更新后&#xff0c;打开Edge浏览器&#xff0c;无论复制什么内容&#xff0c;都会弹出Copilot人工智能插件&#xff0c;非常令人反感&#xff0c;网上搜索的关闭方法都非常麻烦&#xff0c;比如&#xff1a;组策略和注册表。自己摸索得出最简便有效的关闭方法。 1、…

【java毕业设计】 基于Spring Boot+mysql的高校心理教育辅导系统设计与实现(程序源码)-高校心理教育辅导系统

基于Spring Bootmysql的高校心理教育辅导系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于Spring Bootmysql的高校心理教育辅导系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及…

一致性hash

一、什么是一致性hash 普通的hash算法 (hashcode % size )&#xff0c;如果size发生变化&#xff0c;几乎所有的历史数据都需要重hash、移动&#xff0c;代价非常大&#xff0c;常见的java中的hashmap就是如此。 那如果在hash表扩容或者收缩的时候size能够保持不变&#xff0…

gitee / github 配置git, 实现免密码登录

文章目录 怎么配置公钥和私钥验证配置成功问题 怎么配置公钥和私钥 以下内容参考自 github ssh 配置&#xff0c;gitee的配置也是一样的&#xff1b; 粘贴以下文本&#xff0c;将示例中使用的电子邮件替换为 GitHub 电子邮件地址。 ssh-keygen -t ed25519 -C "your_emai…

线性代数 --- 矩阵的对角化以及矩阵的n次幂

矩阵的对角化以及矩阵的n次幂 &#xff08;特征向量与特征值的应用&#xff09; 前言&#xff1a; 在上一篇文章中&#xff0c;我记录了学习矩阵的特征向量和特征值的学习笔记&#xff0c;所关注的是那些矩阵A作用于向量x后&#xff0c;方向不发生改变的x(仅有尺度的缩放)。线…

VMware 15 安装centos7虚拟机

1. 安装前准备 1.1 下载centos 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 下载需要版本的centos版本 直达链接 centos7.9 &#xff1a; centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云 .基础使用的话安装选择这个就行了&#xff0c;大概下载几分钟 2. …

linux负载均衡 和 系统负载分析笔记

1 负载均衡 1.1 计算负载 1.1.1 PELT算法简介 从Linux3.8内核以后进程的负载计算不仅考虑权重&#xff0c;⽽且跟踪每个调度实体的历史负载情况&#xff0c;该算法称为PELT(Per-entity Load Tracking) 《奔跑吧Linux内核》卷1&#xff1a;基础架构&#xff1b;P505 相关资料…