ReactNative——导航器react-navigation(堆栈式导航器篇)

2023-11-07

react-navigation

安装核心包

yarn add @react-navigation/native

安装@react-navigation/native本身依赖的相关包

react-native-reanimated:动画库

react-native-gesture-handler:手势库

react-native-screens:使用原生代码实现screen容器可以提高性能流畅度

react-native-safe-area-context:可以让我们的组件渲染在一个安全的区域(比如有些移动设备是异性的,刘海屏、挖孔屏等)

@react-native-community/masked-view:堆栈式导航器所依赖的库

yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

React Native 0.60以上,链接是自动的,因此不需要运行react原生链接。

但在iOS开发上,则需要安装pod来完成链接

cd ios 
pod install

打开android/app/src/main/java/<your package name>/MainActivity.java

加入以下代码

public class MainActivity extends ReactActivity {
  // ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
  }
  // ...
}

在该文件顶部加入

import android.os.Bundle;

在项目入口文件引入@react-navigation/native

import { NavigationContainer } from '@react-navigation/native';

如何使用堆栈式导航器

安装核心库

yarn add @react-navigation/stack

比如说写一个home组件

import React from 'react';
import { View, Text } from 'react-native';

class Home extends React.Component {
    render() {
        return (
            <View>
                <Text>Home</Text>
            </View>    
        )
    }
}

export default Home;

再写一个Detail组件

import React from 'react';
import { View, Text } from 'react-native';

class Detail extends React.Component {
    render() {
        return (
            <View>
                <Text>Detail</Text>
            </View>    
        )
    }
}

export default Detail;

然后在navigator下新建个文件夹index.tsx

import React from 'react';
import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import Home from '@/pages/Home';
import Detail from '@/pages/Detail';

type RootStackPareamList = {
    Home: undefined;
    Detail:undefined;
}


let Stack = createStackNavigator<RootStackPareamList>();
/*{
    Navigator, // 导航器
    Screen // 路由,也就是页面
}
*/

class Navigator extends React.Component {
    render(){
        return (
            <NavigationContainer>
                <Stack.Navigator>
                    <Stack.Screen name="Home" component={Home}/>
                    <Stack.Screen name="Detail" component={Detail}/>
                </Stack.Navigator>
            </NavigationContainer>);
    }
}

export default Navigator;

然后在src/index.tsx

import Navigator from '@/navigator/index';

export default Navigator;

可以发现Android和ios的标题显示不一样,这是因为ios和Android的默认设计风格不一样导致的。

如何统一ios和Android的标题风格呢

使用screanOptions属性就好,在Stack.Screen里也有options属性,这样就可以单独设置某个页面的标题样式了,还有一些常用的属性 如:headerTitle:'首页'

import React from 'react';
import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import Home from '@/pages/Home';
import Detail from '@/pages/Detail';

type RootStackPareamList = {
    Home: undefined;
    Detail:undefined;
}


const Stack = createStackNavigator<RootStackPareamList>();
/*{
    Navigator, // 导航器
    Screen // 路由,也就是页面
}
*/

class Navigator extends React.Component {
    render(){
        return (
            <NavigationContainer>
                <Stack.Navigator
                    screanOptions={{
                        headerTitleAlign:'center',
                    }}>
                    <Stack.Screen options={{ headerTitleAlign:'left, headerTitle:'首页'}} name="Home" component={Home}/>
                    <Stack.Screen name="Detail" component={Detail}/>
                </Stack.Navigator>
            </NavigationContainer>);
    }
}

export default Navigator;

页面间的跳转如何实现?

import React from 'react';
import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import Home from '@/pages/Home';
import Detail from '@/pages/Detail';
import {
  createStackNavigator,
  StackNavigationProp,
} from '@react-navigation/stack'; // 自动引入

type RootStackPareamList = {
    Home: undefined;
    Detail:undefined;
}

// 加这一行
export type RootStackNavigation = StackNavigationProp<RootStackPareamList>


const Stack = createStackNavigator<RootStackPareamList>();
/*{
    Navigator, // 导航器
    Screen // 路由,也就是页面
}
*/

class Navigator extends React.Component {
    render(){
        return (
            <NavigationContainer>
                <Stack.Navigator
                    headerMode="float"
                    screanOptions={{
                        headerTitleAlign:'center',
                    }}>
                    <Stack.Screen options={{ headerTitleAlign:'left, headerTitle:'首页'}} name="Home" component={Home}/>
                    <Stack.Screen name="Detail" component={Detail}/>
                </Stack.Navigator>
            </NavigationContainer>);
    }
}

export default Navigator;

tips:

headerMode="float"所有页面共用一个标题栏(ios的默认)

headerMode="none"没有标题栏

headerMode="screen"每个页面都有一个标题栏(Android的默认)

在Home组件中使用

import React from 'react';
import { View, Text, Button } from 'react-native';
import { RootStackNavigation } from '@/navigator/index'

interface IProps {
    navigation:RootStackNavigation;
}

class Home extends React.Component<IProps> {

    onPress = () => {
        const {navigation} = this.props;
        navigation.navigate("Detail");
    }
    
    render() {
        return (
            <View>
                <Text>Home</Text>
                <Button title="跳转到详情页" onPress={this.onPress}/>
            </View>    
        )
    }
}

export default Home;

目前这样跳转是比较生硬的。

如何产生一个跳转的动画效果?

让前一个页面的从左边划走,然后后一个页面从右往左进来,透明度从0到1渐变

可以使用headerStyleInterpolator:HeaderStyleInterpolators.forUIKit,ios就能实现上述效果

使用cardStyleInterpolator:CardStyleInterpolators.forHorizontalIOS,Android也能实现跟ios类似的效果了

<Stack.Navigator
    headerMode="float"
    screanOptions={{
        headerTitleAlign:'center',
        headerStyleInterpolator:HeaderStyleInterpolators.forUIKit,
        cardStyleInterpolator:CardStyleInterpolators.forHorizontalIOS,
    }}>
</Stack.Navigator>

但是可以发现ios是可以通过手势操作关闭详情页得,但是Android是不可以得,因为ios默认开启手势,Android默认不开启

使用gestureEnabled:true,开启手势系统,然后会神奇的发现,Android从左向右滑动还是无法关闭详情页,因为Android默认的手势方向是垂直方向,所以往下滑就能关闭详情页,如何让它像ios那样向右滑动可以关闭呢?

继续设置手势方向为水平即可:gestureDirection:'horizontal',

<Stack.Navigator
    headerMode="float"
    screanOptions={{
        headerTitleAlign:'center',
        headerStyleInterpolator:HeaderStyleInterpolators.forUIKit,
        cardStyleInterpolator:CardStyleInterpolators.forHorizontalIOS,
        gestureEnabled:true,
        gestureDirection:'horizontal',
    }}>
</Stack.Navigator>

仔细观察会发现,Android的显示没有ios美观。

如何针对Android写样式呢?

【安卓改善前效果如下图】

【改善后的Android效果】,左边阴影去掉了,也去掉了标题的下边框阴影

使用headerStyle

<Stack.Navigator
    headerMode="float"
    screanOptions={{
        headerTitleAlign:'center',
        headerStyleInterpolator:HeaderStyleInterpolators.forUIKit,
        cardStyleInterpolator:CardStyleInterpolators.forHorizontalIOS,
        gestureEnabled:true,
        gestureDirection:'horizontal',
        headerStyle: {
            ...Platform:select({
                android: {
                    elevation:0,
                    borderBottomWidth:StyleSheet.hairlineWidth,
                }
            })
        },
    }}>
</Stack.Navigator>

页面跳转间如何传参呢?

这是开发种十分常见的场景,如进入详情页,肯定需要在跳转的时候传递id的

那么需要在src/navigator/index.tsx种修改(就是导航组件的位置,你的项目不一定在这个路径)

设置一下详情页接收参数的类型,因为后续在Detail需要用到这个类型,因此再加个export导出

export type RootStackPareamList = {
    Home: undefined;
    Detail:{
        id:number;
    }
}

然后再Home组件,增加传递参数的逻辑

// home组件里的那个跳转方法
onPress = () => {
    const {navigation} = this.props;
    navigation.navigate("Detail",{
        id:100,
    }); // 这里增加了传参~
}

在Detail组件接收即可

import React from 'react';
import { View, Text } from 'react-native';
import { RootStackParamList } from '@/navigator/index';

interface IProps {
    route:RouteProp<RootStackParamList,'Detail'>;
}

class Detail extends React.Component<IProps> {
    render() {
        const { route } = this.props
        return (
            <View>
                <Text>Detail</Text>
                <Text>{route.params.id}</Text>
            </View>    
        )
    }
}

export default Detail;

后续再写一个标签导航器~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ReactNative——导航器react-navigation(堆栈式导航器篇) 的相关文章

  • 获取 CRM 2011 中功能区按钮的 ID

    我创建了一个 JavaScript 我想在其中隐藏功能区Reactivate Lead按钮取决于某些条件 我通过在表单上按 F12 获得了按钮的 ID 即lead NoRelationship Form Mscrm Form lead Re
  • 无法处理未捕获的类型错误:无法读取 createRouterReducer 处未定义的属性“位置”

    我在将路由器连接到 rootReducer 时遇到问题 控制台日志 未捕获的类型错误 无法读取未定义的属性 位置 在 createRouterReducer reducer js 005c 9 不知道如何修复它并将路由器连接到减速器 app
  • 如何使传单圆圈标记可拖动?

    使用传单 我创建了一个L circleMarker我希望它是可拖动的 var marker L circleMarker new L LatLng 48 94603 2 25912 draggable true bindPopup Circ
  • CSS 内边框?

    我纯粹用 CSS 创建了左侧的按钮 它是一个div 中的一个div 然而 右侧的三个按钮是background属性于img标签 我这样做是为了按照以下说明模拟翻转效果here http kyleschaeffer com best prac
  • “React”在定义之前就被使用了

    我正在使用 create react app typescript eslint 应用程序 在构建过程中出现这样的错误 Line 1 8 React was used before it was defined typescript esl
  • 每n秒执行一次函数

    我制作了这个在 10 秒后点击链接的代码片段 function timeout window setTimeout function img left click 1000 setTimeout timeout 1000 timeout 我
  • html 图像 src 调用 javaScript 变量

    这是我的代码 我想问 我怎样才能做到这一点 img src img apple 我一直在尝试使用 call 函数和 document onload 但它根本不起作用 有人可以救我吗 我假设你只是想用 javascript 更新图像 src
  • 有没有办法在 React 中自动播放音频而不使用 onClick 事件?

    我在尝试在 componentDidMount 中播放音频时收到此错误 未捕获 承诺中 DOMException play 失败 因为用户没有先与文档交互 componentDidMount document getElementById
  • Twitter Bootstrap - 下拉菜单 - 箭头键不适用于 Firefox 中的输入标签

    要求 我想在带有用户名和密码字段的下拉菜单中放置一个登录表单 我可以做到这一点 除了以下问题之外 一切正常 Issue 打字时我无法使用箭头键 上 下 firefox 当输入位于下拉代码之外时 这很有效 这适用于其他浏览器 例如 googl
  • jslint 配置 |传递全局变量

    我如何提醒 jshint 我有全局变量 即命名它们 我知道你可以做到这一点 但我不记得语法了 我在这里定义了一个全局的 function window glob1 local var 稍后像这样使用 不同的 IIFE function gl
  • 如何用 JavaScript 修复图像透视变形和旋转?

    我有一些用手机拍摄的图像 有没有可以拉直纸张照片并将其压平的 JavaScript 库 例如 我想创建一个矩形图像 该图像没有任何失真 换句话说我想知道如何用 JavaScript 修复透视变形和旋转 例如 我发现下面的示例图像来自this
  • JQuery $.ajax() 在 java servlet 中发布数据

    我想将数据发送到 java servlet 进行处理 数据将具有可变长度并采用键 值对 A1984 1 A9873 5 A1674 2 A8724 1 A3574 3 A1165 5 数据不需要这样格式化 这就是我现在的方式 var sav
  • ES6 静态方法引用 self? [复制]

    这个问题在这里已经有答案了 我有两节课 存储库和用户存储库 我想在 Repository 中定义一个静态方法 该方法在运行时调用 UserRepository 中的静态函数 有什么干净的方法可以做到这一点吗 class Repository
  • 在循环中调用 setTimeout 未按预期工作

    下面的 JavaScript 应该 在我看来 以 0 5 秒的间隔播放一系列音符 但它会将它们全部作为一个同时的和弦来演奏 知道如何修复它吗 function playRecording if notes length gt 0 for v
  • 如何使用 Javascript 在 html 文件中搜索字符串?

    我有 5 个 html 文件 并且有一个搜索表单 我想用它来搜索这些 html 文件中的文本
  • 从请求url获取hash参数

    我有这样的网址 http www coolsite com daily plan id 1 http www coolsite com daily plan id 1解析该字符串并读取哈希值 id 之后的值 的最简单方法是什么 谢谢 在客户
  • 如果 jquery 验证激活,如何在单选按钮中放置红色边框[重复]

    这个问题在这里已经有答案了 我的问题是 如果 jquery 验证像示例图片中那样激活 我无法使单选按钮具有红色边框 任何人都可以帮我解决这个问题吗 http i38 photobucket com albums e149 eloginko
  • 在 Meteor 应用程序中实现 MongoDB 2.4 的全文搜索

    我正在考虑向 Meteor 应用程序添加全文搜索 我知道 MongoDB 现在支持此功能 但我对实现有一些疑问 启用文本搜索功能的最佳方法是什么 textSearchEnabled true 在 Meteor 应用程序中 有没有办法添加索引
  • highchart堆积柱每个类别的总数据

    我想获取每个类别的总数据 这point stackTotal只给出活动数据的总数 从我粘贴的代码示例中 我想知道每种水果的总消耗量 因此 即使我单击右上角图例上的乔的名字 这使得堆叠图表上的所有乔信息都处于非活动状态 我仍然可以知道约翰 简
  • 使用
    元素作为 JavaScript 代码的输入。这是最好的方法吗?

    各位 显然 我是编码新手 所以最近完成了一些有关 HTML 和 Javascript 的 Lynda 课程后 我的简单 HTML 页面遇到了困难 基本上 我想要的是使用 JavaScript 进行基本计算 让用户使用 HTML 输入两个数字

随机推荐

  • springboot项目部署宝塔提示成功,实际没有启动

    被这个问题搞得头大了 默认项目用户为www 把项目用户改成root即可启动成功 启动成功后 再刷新还是显示成功运行
  • web测试的基本测试点

    一 什么是Web测试 如果要了解web测试 首先我们的清楚web项目是什么 一般指本b s架构项目也就是通过浏览器进行访问的 在日常生活工作中 基于web系统的应用非常多 打开电脑 抢火车票我们会登陆12306网站 添置衣物我们会登陆天猫
  • Codeforces 996 A Hit the Lottery

    A Hit the Lottery time limit per test 1 second memory limit per test 256 megabytes input standard input output standard
  • 副业搞钱的几个野路子:两个年入10万的零成本赚钱项目

    不想担太多风险 想低成本歪主意 最佳的选择不外乎就是做服务和卖交互式产品 搞交互式项目 最大的成本是时间成本 很多人都不缺时间 缺的是歪主意思维和变通能力 独豆豆不如众豆豆 这几天辨认出了三个歪主意的野路子 写个文章给大家互动互动 这三个主
  • Fisco Bcos区块链二(搭建使用控制台,体验Holleworld合约调用)

    文章目录 区块链开荒 技术文档 https fisco bcos documentation readthedocs io zh CN latest index html 2 配置及使用控制台 1 准备依赖 2 启动并使用控制台 3 部署及
  • 100天精通Python(可视化篇)——第97天:Pyecharts绘制多种炫酷热力图参数说明+代码实战

    文章目录 专栏导读 1 热力图介绍 2 基础热力图 3 添加色块数值 4 添加热力标尺 5 修改色块颜色 6 不同区间颜色 7 炫酷模块1 8 炫酷模块2 书籍推荐 专栏导读 本文已收录于 100天精通Python从入门到就业 本专栏专门针
  • 【构建ML驱动的应用程序】第 8 章 :部署模型时的注意事项

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 最大堆和最小堆

    堆和栈的区别 一 堆栈空间分配区别 1 栈 操作系统 由操作系统自动分配释放 存放函数的参数值 局部变量的值等 其操作方式类似于数据结构中的栈 2 堆 操作系统 一般由程序员分配释放 若程序员不释放 程序结束时可能由OS回收 分配方式倒是类
  • 【从零开始】力扣刷题(2)

    前言 我根据这里的表单开始刷力扣 数组的改变移动 453 最小操作次数使元素相等 写了一个但超过时间限制 碰到 1 100000000 就超出时间限制了 就不错误示范了 看了一个评论 拍案叫绝 665 非递减数列 想了一天 看了很多解答 好
  • 【数据结构2】算法的基本概念

    算法的基本概念 程序 数据结构 算法 数据结构 如何把现实世界的问题信息化 将信息存进计算机 同时还要实现对数据结构的基本操作 算法 如何处理这些信息 以解决实际问题 算法的特性 有穷性 一个算法必须总在执行有穷步之后结束 且每一步都可在有
  • Windows 快速配置ip地址

    说明 生活中 很多时候我们要背着电脑往返于某些固定的地方 家里 公司 实验室 寝室等等 每次开电脑后第一件事情就是用图形界面点点点点再点改IP地址 这样非常的麻烦 如何快速配置为自己量身定做的IP地址呢 当然是用脚本 bat 脚本 将下面脚
  • Stata数据处理

    作者 Economicoder 公众号 数据学徒 1 快捷键 Fn F2 描述数据 describe Fn PgUp 搜索先前命令 Ctrl 8 打开 data editor browse Ctrl 9 新建do文档 Ctrl D 执行在d
  • 图片转换js (img对象,file对象,base64,canvas对象),以及图片压缩方式

    首先想一想我们有哪些需求 大多时候我们需要将一个File对象压缩之后再变为File对象传入到远程图片服务器 有时候我们也需要将一个base64字符串压缩之后再变为base64字符串传入到远程数据库 有时候后它还有可能是一块canvas画布
  • 【blog】使用github-pages搭建个人博客

    我的博客 以此博客记录学习过程及相关学习笔记 一 选择模板 1 在Jekyll Themes 或者jekyll sites 选择一个你喜欢的模板直接下载 2 在github新建一个项目 选择一个主题 外链图片转存失败 源站可能有防盗链机制
  • 数据库的模糊查询

    命中率越高 策略越好 数据库的模糊查询 work918 在SQL中 模糊查询可以使用LIKE关键字来实现 LIKE关键字后面可以跟一个模式 其中 表示任意数量的字符 表示一个字符 例如 如果你想在一个名为students的表中查找所有名字以
  • python计算正方形、立方体、圆、球的面积和体积

    usr bin env python encoding UTF 8 import math 正方形的面积 def square mianji x return x x 立方体的表面积 def cube x return xx6 立方体的体积
  • linux系统下部署02-InfluxDB的安装和设置密码

    InfluxDB是一个当下比较流行的时序数据库 InfluxDB使用 Go 语言编写 无需外部依赖 安装配置非常方便 适合构建大型分布式系统的监控系统 一 InfluxDB 简介 InfluxDB 是用Go语言编写的一个开源分布式时序 事件
  • 使用高效代理抓取58同城巴州二手房信息并保存至excel

    声明 此程序旨在技术学习交流 促进网络安全 不作任何商业用途 违者责任自负 此程序就是使用代理IP来反爬的一个小案例 使用的高效代理 通过API每次请求提取一个代理IP 一个代理IP 必须是高匿代理 隐藏真实IP 相当于一台主机 只要主机足
  • 无需解密代码!软件保护专家VMProtect 2020全新升级!更丰富的保护功能

    VMProtect是新一代的软件保护实用程序 具有内置的反汇编程序 可与Windows和Mac OS X可执行程序配合使用 还可以链接编译器创建的MAP文件 以快速选择代码片段进行保护 VMProtect的基本原则是通过使应用程序代码和逻辑
  • ReactNative——导航器react-navigation(堆栈式导航器篇)

    react navigation 安装核心包 yarn add react navigation native 安装 react navigation native本身依赖的相关包 react native reanimated 动画库 r