【React Native】学习记录(二)——路由搭建和常见的开发技巧

news2024/9/28 21:25:37

模拟器设置成中文

在开发过程中发现,两个模拟器都不能输入中文,所以需要配置一下。

先说一下安卓,在弹出的输入框中查看设置,设置一下对应的languages即可:
在这里插入图片描述在苹果模拟器中,跟苹果手机一样,打开设置,然后打开通用,同样设置语言:
在这里插入图片描述

路由搭建

我在这里走了弯路,去了另一个库…,路由文档入口在这:链接

sudo npm install @react-navigation/native
# 兼容expo
sudo npx expo install react-native-screens react-native-safe-area-context
# 路由跳转的本质是堆栈
sudo npm install @react-navigation/native-stack
# 我们项目中会使用到底部导航栏跳转
sudo npm install @react-navigation/bottom-tabs

我要做的东西如下:
在这里插入图片描述
大概也能猜出哪些路由了,这里说一下路由中tab页面和普通页面的搭建,关于抽屉页面,后续使用了再补上:

// router/index.js
import react from 'react';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Feather } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';

import HabitHome from '../views/habit/home/index';
import HabitDetail from '../views/habit/detail/index';
import HabitSet from '../views/habit/set';
import DateHome from '../views/date/home/index';
import DateSet from '../views/date/set/index';


// 这里声明了底部tab页面有哪些,还配置了顶部导航栏的一些自定义按钮
const Tab = createBottomTabNavigator();

function TabStack(){
    return (
        <Tab.Navigator 
        screenOptions={{ 
          headerShown: true,
          tabBarInactiveTintColor: '#333',
          tabBarActiveTintColor: '#6528F7',
          tabBarShowLabel: true,
        }}>
            <Tab.Screen 
              name="HabitHome" 
              component={HabitHome}
              options={{
                title: '',
                tabBarLabel: '打卡',
                tabBarIcon: ({ color, size }) => (
                  <Feather name="target" color={color} size={size} />
                ),
              }} />
            <Tab.Screen 
            name="DateHome" 
            component={DateHome}
            options={{
              title: '',
              tabBarLabel: '纪念日',
              tabBarIcon: ({ color, size }) => (
                <MaterialCommunityIcons name="calendar-heart" color={color} size={size} />
              ),
            }} />
        </Tab.Navigator>
    )
}

// 将底部导航栏和非底部导航栏的页面都写在这里:
const Stack = createNativeStackNavigator();

function PageStack(){
  return (
    <Stack.Navigator>
      <Stack.Screen
          name="TabStack"
          component={TabStack}
          options={{ headerShown: false }}
      />
      <Stack.Screen name="HabitDetail" component={HabitDetail} options={{ title: '习惯详情' }} />
      <Stack.Screen 
        name="HabitSet" 
        component={HabitSet}
        options={{
          title: '添加一个习惯'
        }} />
      <Stack.Screen name="DateSet" component={DateSet} options={{ title: '设置纪念日' }} />
    </Stack.Navigator>
  )
}

export default PageStack;


接下来就是在App.js中使用了:

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { Provider } from 'react-redux'
import store from './store/index'
import  PageStack from './router/index'

function App() {
  return (
    <Provider store={store}>
      <NavigationContainer>
        <PageStack />
      </NavigationContainer>
    </Provider>
  );
}

export default App;

用的状态管理器,还是redux,像以前在普通react项目中那样使用就行(官网地址)

开发技巧

  1. ScrollView适合用来显示数量不多的滚动元素。放置在ScrollView中的所有组件都会被渲染(还没滑动到下一屏幕,也是会被渲染出来),FlatList更适于长列表数据,且元素个数可以增删,和ScrollView不同的是,FlatList并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。综上,如果列表太长的情况下,可以优先使用FlatList
  2. View组件类似Div组件,但是没有点击事件;
  3. 所有文字必须包含在Text组件中;
  4. Button组件在两端的机器上显示的不一样,所以为了确保样式一致性,我会使用View按钮来制作按钮;
  5. 由于View上没有点击事件,所以我借助了TouchableOpacity,而安卓机上还有一个特有的组件:TouchableNativeFeedback,做了如下封装:
import { TouchableOpacity, TouchableNativeFeedback, Platform } from 'react-native';

function CommonButton (props){
    const { onPress, children } = props;

    if(Platform.OS === 'android') {
        return (
            <TouchableNativeFeedback 
                background={TouchableNativeFeedback.Ripple('rgba(215, 187, 245, 0.5)', false)}
                onPress={onPress}>
                { children }
            </TouchableNativeFeedback>
        )
    }else {
        return (
            <TouchableOpacity onPress={onPress}>
                { children }
            </TouchableOpacity>
        )
    }
}

export default CommonButton;

  1. 从上面的例子可知Platform可以用来判断端的类型,如果你觉得一个文件编写两套代码麻烦,可以改成下面的方式:
- common-button.ios.js
- common-button.android.js

在引入文件的时候还是直接写:

import CommonButton from 'xxx/xxx/common-button'
  1. React Native中的flex跟平常的还是有些区别的;

  2. 由于样式的局限性,所以在项目中我想借助float来写瀑布流样式是不支持的,后来实现的方法是采用了拆分成了两列:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fQuwCW3t-1690621985158)(https://secure2.wostatic.cn/static/9SKFkgGqbqcWtHmMG27MnZ/image.png?auth_key=1690620869-5JGFqRM7Ev1dD1bFSa1e8W-0-54ef38f68cb2afb27421cf15a936125c)]

  3. 生成随机数有很多种npm包供使用,比如nanoid,但是它不兼容React Native,这里采用了uuid:

npm i uuid react-native-get-random-values
// store/modules/habit

import { createSlice } from '@reduxjs/toolkit';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';

const defaultList = [
    {
        id: uuidv4(10),
        name: '打卡',
        count: 0,
    },
]

// ...
  1. expo包内置了图标,文档地址:@expo/vector-icons;
  2. 路由跳转,在页面props中可以获取navigation对象:
function HabitHome(props) {
  const { navigation } = props;
  
  // ...
  
  // 新增打卡
  const goSetPage = () => {
    navigation.navigate('HabitSet')
  }
  
  // ...
}
  1. 当用户在输入某些内容,会弹出键盘,键盘有时候会挡住页面,可以借助KeyboardAvoidingView组件,本组件可以自动根据键盘的高度,调整自身的 height 或底部的 padding,以避免被遮挡;
  2. 另外键盘弹出之后,我们希望可以在点击其他地方的时候自动收回键盘,那么可以借助TouchableWithoutFeedback,最终代码如下:
function HabitSet(props) {
  // ...

  // 收起键盘
  const onPress = () => {
    Keyboard.dismiss();
  }
  
  return (
    <TouchableWithoutFeedback onPress={onPress}>
      <KeyboardAvoidingView style={styles.container} behavior={Platform.OS == "ios" ? "padding" : "height"}>
        // ...
      </KeyboardAvoidingView>
    </TouchableWithoutFeedback>
  );
}

参考

  • expo
  • react native
  • react-navigation
  • 图标
  • 配色参考
  • react-redux

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

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

相关文章

Python web实战 | 用Docker部署Django项目

1. Docker与Django 为什么要使用Docker来部署Django项目&#xff1f;这是因为Docker提供了一个独立、一致的环境&#xff0c;让开发者可以在任何地方运行他们的应用程序&#xff0c;而不用担心环境配置问题。这就像是你有一个可以装下所有工具和材料的宝箱&#xff0c;无论你走…

Linux内存回收入口

概述 内存回收主要是有kswapd异步回收和direct reclaim同步回收两种入口&#xff0c;其中逻辑非常复杂&#xff0c;本文主要只概要描述不同回收场景下内核设计的主要思想&#xff0c;源码细节不同版本有不少区别&#xff0c;具体的分析后续会有专门的文章分析。 页面回收常识&…

【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?

文章目录 前言声明和初始化扩容时机源码分析go1.17go1.18内存对齐 总结 前言 在 Go 语言中&#xff0c;有一个很常用的数据结构&#xff0c;那就是切片&#xff08;Slice&#xff09;。 切片是一个拥有相同类型元素的可变长度的序列&#xff0c;它是基于数组类型做的一层封装…

【LeetCode】二叉树的前序,中序,后序遍历

此题用递归做比较容易&#xff0c;然后根据前中后的遍历特点&#xff1a; 前序是根左右&#xff0c; 中序是左根右&#xff0c; 后序是左右根。 前序遍历&#xff1a;做题入口 class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer…

IntersectionObserver实现小程序长列表优化

IntersectionObserver实现小程序长列表优化 关于 IntersectionObserver 思路 这里以一屏数据为单位【一个分页的10条数据&#xff0c;最好大于视口高度】&#xff0c; 监听每一屏数据和视口的相交比例&#xff0c;即用户能不能看到它 只将可视范围的数据渲染到页面上&#x…

2025年卡脖子技术清零?甚至计划推动鸿蒙欧拉比肩全球领先水平

深圳市工业和信息化局近日发布了推动开源鸿蒙欧拉产业创新发展的行动计划&#xff0c;以推动鸿蒙欧拉在2023至2025年期间成为全球领先操作系统&#xff0c;并构建全球信息技术体系&#xff0c;实现我国操作系统技术创新和自主发展目标。 该计划旨在加强操作系统技术能力&#x…

造个轮子--用Python写个语法解析器

文章目录 前言选型针对人群目标技术实现本文目标 效果实现字符指针错误类型语法解析交互 前言 目的纯粹&#xff0c;基于Python做一个简单的新的简单的编程语言。一方面是开拓视野&#xff0c;另一方面是作为毕设的临时过渡方案&#xff08;没错&#xff0c;先前提到的算法平台…

抖音短视频矩阵系统源码:SEO优化开发解析

抖音短视频矩阵系统源码是一个基于抖音短视频平台的应用程序。它允许用户上传和观看短视频&#xff0c;以及与其他用户交互。SEO优化开发解析是指对该系统进行搜索引擎优化的开发解析。 一、 在进行SEO优化开发解析时&#xff0c;可以考虑以下几点&#xff1a; 关键词优化&…

【Python数据分析】Python常用内置函数(一)

&#x1f389;欢迎来到Python专栏~Python常用内置函数&#xff08;一&#xff09; ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;Python学习专栏 文章作者技术和水平有限&#xff0c;如果文…

在撰写公文时,要注意使用正确的格式和样式

在撰写公文时&#xff0c;注意使用正确的格式和样式&#xff0c;以符合公文的规范要求是非常重要的。 公文是一种正式文书&#xff0c;需要遵循一定的格式和样式要求&#xff0c;以符合公文的规范和标准。在撰写公文时&#xff0c;需要注意以下几点&#xff1a; 1.文字排版&…

day46-Quiz App(测试题计分)

50 天学习 50 个项目 - HTMLCSS and JavaScript day46-Quiz App&#xff08;测试题计分&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" conte…

【matlab】机器人工具箱快速上手-动力学仿真(代码直接复制可用)

动力学代码&#xff0c;按需修改参数 各关节力矩-关节变量的关系曲线&#xff1a; %%%%%%%%SCARA机器人仿真模型 l[0.457 0.325]; L(1) Link(d,0,a,l(1),alpha,0,standard,qlim,[-130 130]*pi/180);%连杆1 L(2)Link(d,0,a,l(2),alpha,pi,standard,qlim,[-145 145]*pi/180);%连…

代理模式--静态代理和动态代理

1.代理模式 定义&#xff1a;代理模式就是代替对象具备真实对象的功能&#xff0c;并代替真实对象完成相应的操作并且在不改变真实对象源代码的情况下扩展其功能&#xff0c;在某些情况下&#xff0c;⼀个对象不适合或者不能直接引⽤另⼀个对象&#xff0c;⽽代理对象可以在客户…

华为OD机试真题 Java 实现【最长公共后缀】【2023 B卷 100分】,等于白送

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明4、再输入5、再输出 七、机考攻略 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff…

【Golang】Golang进阶系列教程--Go 语言数组和切片的区别

文章目录 前言数组声明以及初始化函数参数 切片声明以及初始化函数参数 总结 前言 在 Go 语言中&#xff0c;数组和切片看起来很像&#xff0c;但其实它们又有很多的不同之处&#xff0c;这篇文章就来说说它们到底有哪些不同。 数组和切片是两个常用的数据结构。它们都可以用…

LBERT论文详解

论文地址&#xff1a;https://arxiv.org/abs/2105.07148 代码地址&#xff1a;https://github.com/liuwei1206/LEBERT 模型创新 LEBRT采用句子中的词语对&#xff08;论文中称为Char-Word Pair&#xff09;的特征作为输入作者设计Lexicon adapter&#xff0c;在BERT的中间某一…

Codeforces Round 839 (Div. 3)E题解

文章目录 [Permutation Game](https://codeforces.com/contest/1772/problem/E)问题建模问题分析1.分析一个玩家想要获胜的关键2.分析阻塞元素的类别3.分析阻塞元素的类别对于局面的影响代码 Permutation Game 问题建模 给定一个长度为n的排列&#xff0c;排列的每个元素都被阻…

CentOS 7安装PostgreSQL 15版本数据库

目录 一、何为PostgreSQL&#xff1f; 二、PostgreSQL安装 2.1安装依赖 2.2 执行安装 2.3 数据库初始化 2.4 配置环境变量 2.5 创建数据库 2.6 配置远程 2.7 测试远程 三、常用命令 四、用户创建和数据库权限 一、何为PostgreSQL&#xff1f; PostgreSQL是以加州大学…

DGNN Survey

Dynamic Graph Definition G ( V , E , X ) G (V, E, X) G(V,E,X) V v 1 , v 2 , . . . , v m V {v_1, v_2, ..., v_m} Vv1​,v2​,...,vm​ E e i , j E {e_{i, j}} Eei,j​ , e i , j ( v i , v j , f i , j ) e_{i,j} (v_i, v_j, f_{i,j}) ei,j​(vi​,vj​,fi,j​…

M1/M2 通过VM Fusion安装Win11 ARM,解决联网和文件传输

前言 最近新入了Macmini M2&#xff0c;但是以前的老电脑的虚拟机运行不起来了。&#x1f605;&#xff0c;实际上用过K8S的时候&#xff0c;会发现部分镜像也跑不起来&#xff0c;X86的架构和ARM实际上还是有很多隐形兼容问题。所以只能重新安装ARM Win11&#xff0c;幸好微软…