分类 默认分类 下的文章

Create React Native project by Expo

https://docs.expo.dev/guides/typescript/#starting-from-scratch-using-a-typescript-template

Use NativeWind

https://www.nativewind.dev/quick-starts/expo
https://www.nativewind.dev/getting-started/typescript

Install these two packages

yarn add nativewind
yarn add --dev tailwindcss

Setup Tailwind CSS

Run this cli to create file tailwind.config.js

npx tailwindcss init

Edit tailwind.config.js as follows

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./App.{js,jsx,ts,tsx}", "./screens/**/*.{js,jsx,ts,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

Create file app.d.ts and edit

/// <reference types="nativewind/types" />

Use react-native-paper

https://callstack.github.io/react-native-paper/4.0/getting-started.html

Import package

yarn add react-native-paper

Edit babel.config.js

module.exports = function(api) {
  api.cache(true)
  return {
    presets: ['babel-preset-expo'],
    plugins: ["nativewind/babel"],
    env: {
      production: {
        plugins: ['react-native-paper/babel'],
      },
    },
  }
}

Edit App.tsx

import { StatusBar } from 'expo-status-bar'
import { View } from 'react-native'
import { Provider as PaperProvider, Button, Paragraph } from 'react-native-paper'
export default function App() {
  return (
    <PaperProvider>
      <View className="flex-1 items-center justify-center bg-white">
        <Button icon="camera" mode="contained" onPress={() => console.log('Pressed')}>
          Press me
        </Button>
        <Paragraph className='text-[#0000ff]'>Paragraph</Paragraph>
        <StatusBar style="auto" />
      </View>
    </PaperProvider>
  )
}

Run

yarn ios

if not working, close App and try:

npx expo run --ios -c

  1. 新建React Native空白项目
  2. 安装依赖:

    yarn add @react-navigation/bottom-tabs react-native-safe-area-context createBottomTabNavigator
  3. 最简洁的tabbar示例,App.tsx里放置代码:

    import * as React from 'react';
    import { Text, View } from 'react-native';
    import { NavigationContainer } from '@react-navigation/native';
    import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
    
    function HomeScreen() {
      return (
     <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
       <Text>Home!</Text>
     </View>
      );
    }
    
    function SettingsScreen() {
      return (
     <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
       <Text>Settings!</Text>
     </View>
      );
    }
    
    const Tab = createBottomTabNavigator();
    
    export default function App() {
      return (
     <NavigationContainer>
       <Tab.Navigator>
         <Tab.Screen name="Home" component={HomeScreen} />
         <Tab.Screen name="Settings" component={SettingsScreen} />
       </Tab.Navigator>
     </NavigationContainer>
      );
    }

    官方文档:https://reactnavigation.org/docs/tab-based-navigation#minimal-example-of-tab-based-navigation

onChange={(e)=>{
  if (! /^\d?(\d+[\.]?\d*)?$/.test(e.target.value) ) return
  setInputVal(e.target.value)
}}

^\d?表示0个或1个数字开头
\d+表示1个或1个以上数字
[.]?表示0个或者1个小数点
\d*表示0个或0个以上的数字
(\d+[.]?\d*)?表示括号里可以重复0遍或0遍以上次数
(\d+[.]?\d)?$表示以(\d+[.]?\d)?结尾

  1. 新建react native项目

    npx create-expo-app -t expo-template-blank-typescript
  2. 根据教程配置https://github.com/expo/config-plugins/tree/main/packages/ffmpeg-kit-react-native

    1. 安装依赖

      yarn add ffmpeg-kit-react-native @config-plugins/ffmpeg-kit-react-native expo-build-properties

      github教程里没说要装expo-build-properties,导致后续步骤报错

    2. app.json里添加

      "plugins": [
        [
          "@config-plugins/ffmpeg-kit-react-native",
          {
            "package": "full-gpl"
          }
        ]
      ]

      关于full-gpl含义:https://github.com/tanersener/mobile-ffmpeg/releases

  3. 根据上述生成ios和android文件夹

    expo prebuild

    ios/Podfile里的iOS版本太旧会导致编译失败,可根据ffmpeg sdk的官方要求更改版本号:https://www.npmjs.com/package/ffmpeg-kit-react-native

  4. App.tsx编写如下代码

    import { StatusBar } from 'expo-status-bar';
    import { StyleSheet, Text, View } from 'react-native';
    import { FFmpegKit, ReturnCode } from 'ffmpeg-kit-react-native'
    import { useEffect } from 'react';
    import * as FileSystem from 'expo-file-system'
    
    export default function App() {
      useEffect(()=>{
        FFmpegKit.execute(`-i https://static-b905bdbb-5254-4483-af4c-16e5bf477a2e.bspapp.com/mpd/wolf.mpd -c copy ${FileSystem.documentDirectory}/${Math.random()}.mp4`)
        .then(async (session) => {
          const returnCode = await session.getReturnCode()
          if (ReturnCode.isSuccess(returnCode)) {
            console.log('SUCCESS')
          } else if (ReturnCode.isCancel(returnCode)) {
            console.log('CANCEL')
          } else {
            console.log('ERROR')
          }
        })
      }, [])
    
      return (
        <View style={styles.container}>
          <Text>Open up App.tsx to start working on your app!</Text>
          <StatusBar style="auto" />
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
      },
    });
  5. 云端编译并在iOS虚拟机上运行

    yarn ios

    看到SUCCESS的log说明ffmpeg运行成功

import BigNumber from "bignumber.js"
export function bigNumberFloor(num: string|number|BigNumber, decimals: number): string {
  return new BigNumber(num).times(10**decimals).idiv(1).div(10**decimals).toFormat()
}
export function bigNumberCeil(num: string|number|BigNumber, decimals: number): BigNumber {
  return new BigNumber(num).times(10**decimals).integerValue(BigNumber.ROUND_CEIL).div(10**decimals)
}