在这里插入图片描述

今天我们用 React Native 实现一个斐波那契数列生成工具,支持生成指定数量的斐波那契数。

状态设计

import React, { useState, useRef } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet, ScrollView, Animated } from 'react-native';

export const Fibonacci: React.FC = () => {
  const [count, setCount] = useState('10');
  const [sequence, setSequence] = useState<number[]>([]);
  
  const buttonAnim = useRef(new Animated.Value(1)).current;
  const itemAnims = useRef<Animated.Value[]>([]).current;

状态设计包含数量、数列、动画值。

数量count 是字符串类型,存储用户输入的数量。默认值 '10',生成前 10 个斐波那契数。

数列sequence 是数字数组,存储生成的斐波那契数列。

两个动画值

  • buttonAnim:按钮的缩放动画
  • itemAnims:数字卡片的动画数组,每个数字一个动画值

为什么数量用字符串?因为 TextInputvalue 必须是字符串。如果用数字,需要在 onChangeText 中转换,在 value 中转回字符串,很麻烦。用字符串存储,只在计算时转换一次。

为什么数字卡片用动画数组?因为要让每个数字依次出现,营造"生成"效果。数组中每个元素对应一个数字的动画值。

生成斐波那契数列

  const generate = () => {
    Animated.sequence([
      Animated.timing(buttonAnim, { toValue: 0.9, duration: 100, useNativeDriver: true }),
      Animated.spring(buttonAnim, { toValue: 1, friction: 3, useNativeDriver: true }),
    ]).start();
    
    const n = Math.min(parseInt(count) || 10, 50);
    const fib: number[] = [0, 1];
    for (let i = 2; i < n; i++) {
      fib.push(fib[i - 1] + fib[i - 2]);
    }

生成函数触发按钮动画,计算斐波那契数列。

按钮动画:序列动画,先缩小到 90%(100ms),再弹回到 100%。营造"按下"的感觉。

解析数量

  • parseInt(count):把字符串转成整数
  • || 10:如果转换失败(NaN),默认 10
  • Math.min(..., 50):限制最大值为 50,防止生成太多数字

初始化数列[0, 1] 是斐波那契数列的前两个数。

循环生成:从索引 2 开始,每次把前两个数相加,加入数组。

  • fib[i - 1]:前一个数
  • fib[i - 2]:前两个数
  • fib[i - 1] + fib[i - 2]:当前数

为什么限制最大值为 50?因为斐波那契数增长很快,第 50 个数已经是 12586269025(125 亿)。生成太多数字会导致:

  1. 界面卡顿(太多卡片)
  2. 数字溢出(JavaScript 的 Number 类型最大安全整数是 2^53 - 1)
  3. 用户体验差(滚动太长)

举例:生成前 5 个斐波那契数。

  • 初始化:[0, 1]
  • i = 2:fib[1] + fib[0] = 1 + 0 = 1,数组变为 [0, 1, 1]
  • i = 3:fib[2] + fib[1] = 1 + 1 = 2,数组变为 [0, 1, 1, 2]
  • i = 4:fib[3] + fib[2] = 2 + 1 = 3,数组变为 [0, 1, 1, 2, 3]

重置和启动动画

    // 重置动画
    itemAnims.length = 0;
    fib.slice(0, n).forEach((_, i) => {
      itemAnims[i] = new Animated.Value(0);
    });
    
    setSequence(fib.slice(0, n));
    
    // 依次显示动画
    itemAnims.forEach((anim, i) => {
      setTimeout(() => {
        Animated.spring(anim, { toValue: 1, friction: 5, useNativeDriver: true }).start();
      }, i * 50);
    });
  };

重置动画数组,设置数列,启动依次显示动画。

重置动画数组

  • itemAnims.length = 0:清空数组
  • forEach 遍历数列,为每个数字创建一个初始值为 0 的动画值

为什么要重置动画数组?因为每次生成数列,数量可能不同。如果不重置,旧的动画值会残留,导致动画错乱。比如第一次生成 10 个数字,第二次生成 5 个数字,如果不重置,前 5 个数字会复用旧的动画值(已经是 1),没有动画效果。

设置数列fib.slice(0, n) 截取前 n 个数字,设置到状态中。

为什么要 slice?因为 fib 数组可能比 n 长。比如用户输入 5,但 fib 数组有 10 个数字(上次生成的)。用 slice(0, n) 截取前 n 个,保证数量正确。

依次显示动画

  • forEach 遍历动画数组
  • setTimeout 延迟 i * 50 毫秒后启动动画
  • 第一个数字延迟 0ms,第二个延迟 50ms,第三个延迟 100ms,依次类推
  • 弹簧动画从 0 到 1,friction: 5 让弹簧有明显回弹

为什么用延迟动画?因为要让数字依次出现,而不是同时出现。延迟时间 i * 50 让每个数字间隔 50ms 出现,营造"生成"效果。如果不延迟,所有数字会同时出现,没有动画效果。

界面渲染:头部和输入

  return (
    <ScrollView style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.headerIcon}>🌀</Text>
        <Text style={styles.headerTitle}>斐波那契数列</Text>
        <Text style={styles.headerSubtitle}>生成斐波那契数列</Text>
      </View>

      <View style={styles.inputSection}>
        <Text style={styles.label}>生成前 N 个斐波那契数</Text>
        <View style={styles.inputRow}>
          <View style={styles.inputWrapper}>
            <TextInput
              style={styles.input}
              value={count}
              onChangeText={setCount}
              keyboardType="numeric"
              placeholder="10"
              placeholderTextColor="#666"
            />
          </View>
          <Animated.View style={{ transform: [{ scale: buttonAnim }] }}>
            <TouchableOpacity style={styles.btn} onPress={generate} activeOpacity={0.8}>
              <Text style={styles.btnText}>🚀 生成</Text>
            </TouchableOpacity>
          </Animated.View>
        </View>
      </View>

头部显示标题和副标题,输入区域包含标签、输入框、按钮。

头部

  • 图标:🌀 螺旋(斐波那契螺旋)
  • 标题:斐波那契数列
  • 副标题:生成斐波那契数列

输入区域

  • 标签:生成前 N 个斐波那契数
  • 输入框:keyboardType="numeric" 弹出数字键盘,textAlign: 'center' 居中对齐
  • 按钮:应用缩放动画,点击时缩小再弹回

为什么输入框居中对齐?因为输入的是数字,居中对齐更美观。文本输入通常左对齐,数字输入通常居中对齐。

数列显示

      {sequence.length > 0 && (
        <View style={styles.result}>
          <Text style={styles.resultTitle}>📊 斐波那契数列</Text>
          <View style={styles.sequence}>
            {sequence.map((num, i) => (
              <Animated.View
                key={i}
                style={[styles.numItem, {
                  transform: [
                    { scale: itemAnims[i] || new Animated.Value(1) },
                    { perspective: 1000 },
                    { rotateY: (itemAnims[i] || new Animated.Value(1)).interpolate({
                      inputRange: [0, 1], outputRange: ['90deg', '0deg']
                    }) },
                  ],
                  opacity: itemAnims[i] || 1,
                }]}
              >
                <Text style={styles.numIndex}>F({i})</Text>
                <Text style={styles.numValue}>{num}</Text>
              </Animated.View>
            ))}
          </View>
        </View>
      )}

数列显示区域用网格布局,每个数字一个卡片。

条件渲染:只有 sequence.length > 0 时才显示。

标题:📊 斐波那契数列

网格布局flexDirection: 'row'flexWrap: 'wrap' 让卡片自动换行。

遍历数列:用 map 遍历 sequence 数组,生成数字卡片。

动画

  • 缩放:从 0 到 1
  • 透明度:从 0 到 1
  • Y 轴旋转:从 90 度到 0 度(翻转效果)
  • 透视:perspective: 1000 让旋转有 3D 效果

插值:把动画值 0-1 映射到旋转角度 90 度到 0 度。卡片从侧面翻转到正面。

数字卡片

  • 索引:F(i) 表示第 i 个斐波那契数
  • 数值:蓝色大字

为什么用翻转动画?因为翻转动画比缩放动画更有趣。卡片从侧面翻转到正面,像翻牌一样,更生动。如果只用缩放,卡片从小到大,比较单调。

为什么显示索引?因为索引能帮助用户理解数列的规律。比如 F(5) = 5,用户可以看到"第 5 个斐波那契数是 5"。如果只显示数值,用户不知道是第几个。

规律说明

      <View style={styles.info}>
        <Text style={styles.infoTitle}>💡 斐波那契数列规律</Text>
        <View style={styles.infoItem}><Text style={styles.infoText}>• F(0) = 0, F(1) = 1</Text></View>
        <View style={styles.infoItem}><Text style={styles.infoText}>• F(n) = F(n-1) + F(n-2)</Text></View>
        <View style={styles.infoItem}><Text style={styles.infoText}>• 每个数是前两个数之和</Text></View>
        <View style={styles.infoItem}><Text style={styles.infoText}>• 相邻两数之比趋近黄金比例 1.618</Text></View>
      </View>
    </ScrollView>
  );
};

规律说明区域显示斐波那契数列的数学规律。

四条规律

  1. 初始值:F(0) = 0, F(1) = 1
  2. 递推公式:F(n) = F(n-1) + F(n-2)
  3. 通俗解释:每个数是前两个数之和
  4. 黄金比例:相邻两数之比趋近 1.618

为什么显示规律?因为规律能帮助用户理解斐波那契数列。很多人知道斐波那契数列,但不知道具体规律。显示规律让用户学习数学知识,增加工具的教育价值。

为什么提到黄金比例?因为黄金比例是斐波那契数列的重要性质。相邻两数之比(比如 5/3 ≈ 1.667,8/5 = 1.6,13/8 = 1.625)越来越接近黄金比例 1.618。这个性质在自然界、艺术、建筑中广泛应用。

鸿蒙 ArkTS 对比:数列生成

@State count: string = '10'
@State sequence: number[] = []

generate() {
  const n = Math.min(parseInt(this.count) || 10, 50)
  const fib: number[] = [0, 1]
  for (let i = 2; i < n; i++) {
    fib.push(fib[i - 1] + fib[i - 2])
  }
  this.sequence = fib.slice(0, n)
}

build() {
  Column() {
    Text('斐波那契数列')
      .fontSize(28)
      .fontWeight(FontWeight.Bold)
    
    Row() {
      TextInput({ text: this.count, placeholder: '10' })
        .type(InputType.Number)
        .onChange((value: string) => {
          this.count = value
        })
      
      Button('🚀 生成')
        .onClick(() => {
          this.generate()
        })
    }
    
    Grid() {
      ForEach(this.sequence, (num: number, i: number) => {
        GridItem() {
          Column() {
            Text(`F(${i})`)
              .fontSize(10)
              .fontColor('#888')
            Text(num.toString())
              .fontSize(14)
              .fontWeight(FontWeight.Bold)
              .fontColor('#4A90D9')
          }
          .backgroundColor('#252550')
          .padding(10)
          .borderRadius(10)
        }
      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
  }
}

ArkTS 中的斐波那契数列生成逻辑完全一样。核心是循环计算,每次把前两个数相加。parseInt()Math.min()push()slice() 都是标准 JavaScript API,跨平台通用。

Grid 和 flexWrap 的区别

  • React Native 用 flexDirection: 'row'flexWrap: 'wrap' 实现网格布局
  • ArkTS 用 Grid 组件,columnsTemplate 定义列数

为什么 ArkTS 用 Grid?因为 ArkTS 提供了专门的网格组件,更符合声明式风格。React Native 没有网格组件,用 Flexbox 模拟。

样式定义

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#0f0f23', padding: 20 },
  header: { alignItems: 'center', marginBottom: 24 },
  headerIcon: { fontSize: 50, marginBottom: 8 },
  headerTitle: { fontSize: 28, fontWeight: '700', color: '#fff' },
  headerSubtitle: { fontSize: 14, color: '#888', marginTop: 4 },
  inputSection: { marginBottom: 20 },
  label: { fontSize: 14, color: '#888', marginBottom: 12 },
  inputRow: { flexDirection: 'row' },
  inputWrapper: { flex: 1, backgroundColor: '#1a1a3e', borderRadius: 12, marginRight: 12, borderWidth: 1, borderColor: '#3a3a6a' },
  input: { padding: 14, fontSize: 18, color: '#fff', textAlign: 'center' },
  btn: { backgroundColor: '#4A90D9', paddingHorizontal: 20, borderRadius: 12, justifyContent: 'center' },
  btnText: { color: '#fff', fontWeight: '700' },
  result: { backgroundColor: '#1a1a3e', padding: 16, borderRadius: 16, marginBottom: 20, borderWidth: 1, borderColor: '#3a3a6a' },
  resultTitle: { fontSize: 16, fontWeight: '600', marginBottom: 16, color: '#fff' },
  sequence: { flexDirection: 'row', flexWrap: 'wrap' },
  numItem: { backgroundColor: '#252550', padding: 10, margin: 4, borderRadius: 10, alignItems: 'center', minWidth: 65 },
  numIndex: { fontSize: 10, color: '#888' },
  numValue: { fontSize: 14, fontWeight: '700', color: '#4A90D9' },
  info: { backgroundColor: '#1a1a3e', padding: 16, borderRadius: 16, borderWidth: 1, borderColor: '#3a3a6a' },
  infoTitle: { fontSize: 16, fontWeight: '600', marginBottom: 16, color: '#fff' },
  infoItem: { marginBottom: 8 },
  infoText: { fontSize: 14, color: '#888' },
});

容器用深蓝黑色背景。输入框居中对齐。数列用网格布局,自动换行。数字卡片最小宽度 65,居中对齐。规律说明用列表布局,每条规律一行。

小结

这个斐波那契工具展示了数列生成和动画效果的实现。用循环计算斐波那契数列,每次把前两个数相加。限制最大值为 50,防止数字溢出。数字卡片用翻转动画依次出现,营造生成效果。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

React Native for OpenHarmony 实战:斐波那契实现

今天我们用 React Native 实现一个斐波那契数列生成工具,支持生成指定数量的斐波那契数。

状态设计

import React, { useState, useRef } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet, ScrollView, Animated } from 'react-native';

export const Fibonacci: React.FC = () => {
  const [count, setCount] = useState('10');
  const [sequence, setSequence] = useState<number[]>([]);
  
  const buttonAnim = useRef(new Animated.Value(1)).current;
  const itemAnims = useRef<Animated.Value[]>([]).current;

状态设计包含数量、数列、动画值。

数量count 是字符串类型,存储用户输入的数量。默认值 '10',生成前 10 个斐波那契数。

数列sequence 是数字数组,存储生成的斐波那契数列。

两个动画值

  • buttonAnim:按钮的缩放动画
  • itemAnims:数字卡片的动画数组,每个数字一个动画值

为什么数量用字符串?因为 TextInputvalue 必须是字符串。如果用数字,需要在 onChangeText 中转换,在 value 中转回字符串,很麻烦。用字符串存储,只在计算时转换一次。

为什么数字卡片用动画数组?因为要让每个数字依次出现,营造"生成"效果。数组中每个元素对应一个数字的动画值。

生成斐波那契数列

  const generate = () => {
    Animated.sequence([
      Animated.timing(buttonAnim, { toValue: 0.9, duration: 100, useNativeDriver: true }),
      Animated.spring(buttonAnim, { toValue: 1, friction: 3, useNativeDriver: true }),
    ]).start();
    
    const n = Math.min(parseInt(count) || 10, 50);
    const fib: number[] = [0, 1];
    for (let i = 2; i < n; i++) {
      fib.push(fib[i - 1] + fib[i - 2]);
    }

生成函数触发按钮动画,计算斐波那契数列。

按钮动画:序列动画,先缩小到 90%(100ms),再弹回到 100%。营造"按下"的感觉。

解析数量

  • parseInt(count):把字符串转成整数
  • || 10:如果转换失败(NaN),默认 10
  • Math.min(..., 50):限制最大值为 50,防止生成太多数字

初始化数列[0, 1] 是斐波那契数列的前两个数。

循环生成:从索引 2 开始,每次把前两个数相加,加入数组。

  • fib[i - 1]:前一个数
  • fib[i - 2]:前两个数
  • fib[i - 1] + fib[i - 2]:当前数

为什么限制最大值为 50?因为斐波那契数增长很快,第 50 个数已经是 12586269025(125 亿)。生成太多数字会导致:

  1. 界面卡顿(太多卡片)
  2. 数字溢出(JavaScript 的 Number 类型最大安全整数是 2^53 - 1)
  3. 用户体验差(滚动太长)

举例:生成前 5 个斐波那契数。

  • 初始化:[0, 1]
  • i = 2:fib[1] + fib[0] = 1 + 0 = 1,数组变为 [0, 1, 1]
  • i = 3:fib[2] + fib[1] = 1 + 1 = 2,数组变为 [0, 1, 1, 2]
  • i = 4:fib[3] + fib[2] = 2 + 1 = 3,数组变为 [0, 1, 1, 2, 3]

重置和启动动画

    // 重置动画
    itemAnims.length = 0;
    fib.slice(0, n).forEach((_, i) => {
      itemAnims[i] = new Animated.Value(0);
    });
    
    setSequence(fib.slice(0, n));
    
    // 依次显示动画
    itemAnims.forEach((anim, i) => {
      setTimeout(() => {
        Animated.spring(anim, { toValue: 1, friction: 5, useNativeDriver: true }).start();
      }, i * 50);
    });
  };

重置动画数组,设置数列,启动依次显示动画。

重置动画数组

  • itemAnims.length = 0:清空数组
  • forEach 遍历数列,为每个数字创建一个初始值为 0 的动画值

为什么要重置动画数组?因为每次生成数列,数量可能不同。如果不重置,旧的动画值会残留,导致动画错乱。比如第一次生成 10 个数字,第二次生成 5 个数字,如果不重置,前 5 个数字会复用旧的动画值(已经是 1),没有动画效果。

设置数列fib.slice(0, n) 截取前 n 个数字,设置到状态中。

为什么要 slice?因为 fib 数组可能比 n 长。比如用户输入 5,但 fib 数组有 10 个数字(上次生成的)。用 slice(0, n) 截取前 n 个,保证数量正确。

依次显示动画

  • forEach 遍历动画数组
  • setTimeout 延迟 i * 50 毫秒后启动动画
  • 第一个数字延迟 0ms,第二个延迟 50ms,第三个延迟 100ms,依次类推
  • 弹簧动画从 0 到 1,friction: 5 让弹簧有明显回弹

为什么用延迟动画?因为要让数字依次出现,而不是同时出现。延迟时间 i * 50 让每个数字间隔 50ms 出现,营造"生成"效果。如果不延迟,所有数字会同时出现,没有动画效果。

界面渲染:头部和输入

  return (
    <ScrollView style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.headerIcon}>🌀</Text>
        <Text style={styles.headerTitle}>斐波那契数列</Text>
        <Text style={styles.headerSubtitle}>生成斐波那契数列</Text>
      </View>

      <View style={styles.inputSection}>
        <Text style={styles.label}>生成前 N 个斐波那契数</Text>
        <View style={styles.inputRow}>
          <View style={styles.inputWrapper}>
            <TextInput
              style={styles.input}
              value={count}
              onChangeText={setCount}
              keyboardType="numeric"
              placeholder="10"
              placeholderTextColor="#666"
            />
          </View>
          <Animated.View style={{ transform: [{ scale: buttonAnim }] }}>
            <TouchableOpacity style={styles.btn} onPress={generate} activeOpacity={0.8}>
              <Text style={styles.btnText}>🚀 生成</Text>
            </TouchableOpacity>
          </Animated.View>
        </View>
      </View>

头部显示标题和副标题,输入区域包含标签、输入框、按钮。

头部

  • 图标:🌀 螺旋(斐波那契螺旋)
  • 标题:斐波那契数列
  • 副标题:生成斐波那契数列

输入区域

  • 标签:生成前 N 个斐波那契数
  • 输入框:keyboardType="numeric" 弹出数字键盘,textAlign: 'center' 居中对齐
  • 按钮:应用缩放动画,点击时缩小再弹回

为什么输入框居中对齐?因为输入的是数字,居中对齐更美观。文本输入通常左对齐,数字输入通常居中对齐。

数列显示

      {sequence.length > 0 && (
        <View style={styles.result}>
          <Text style={styles.resultTitle}>📊 斐波那契数列</Text>
          <View style={styles.sequence}>
            {sequence.map((num, i) => (
              <Animated.View
                key={i}
                style={[styles.numItem, {
                  transform: [
                    { scale: itemAnims[i] || new Animated.Value(1) },
                    { perspective: 1000 },
                    { rotateY: (itemAnims[i] || new Animated.Value(1)).interpolate({
                      inputRange: [0, 1], outputRange: ['90deg', '0deg']
                    }) },
                  ],
                  opacity: itemAnims[i] || 1,
                }]}
              >
                <Text style={styles.numIndex}>F({i})</Text>
                <Text style={styles.numValue}>{num}</Text>
              </Animated.View>
            ))}
          </View>
        </View>
      )}

数列显示区域用网格布局,每个数字一个卡片。

条件渲染:只有 sequence.length > 0 时才显示。

标题:📊 斐波那契数列

网格布局flexDirection: 'row'flexWrap: 'wrap' 让卡片自动换行。

遍历数列:用 map 遍历 sequence 数组,生成数字卡片。

动画

  • 缩放:从 0 到 1
  • 透明度:从 0 到 1
  • Y 轴旋转:从 90 度到 0 度(翻转效果)
  • 透视:perspective: 1000 让旋转有 3D 效果

插值:把动画值 0-1 映射到旋转角度 90 度到 0 度。卡片从侧面翻转到正面。

数字卡片

  • 索引:F(i) 表示第 i 个斐波那契数
  • 数值:蓝色大字

为什么用翻转动画?因为翻转动画比缩放动画更有趣。卡片从侧面翻转到正面,像翻牌一样,更生动。如果只用缩放,卡片从小到大,比较单调。

为什么显示索引?因为索引能帮助用户理解数列的规律。比如 F(5) = 5,用户可以看到"第 5 个斐波那契数是 5"。如果只显示数值,用户不知道是第几个。

规律说明

      <View style={styles.info}>
        <Text style={styles.infoTitle}>💡 斐波那契数列规律</Text>
        <View style={styles.infoItem}><Text style={styles.infoText}>• F(0) = 0, F(1) = 1</Text></View>
        <View style={styles.infoItem}><Text style={styles.infoText}>• F(n) = F(n-1) + F(n-2)</Text></View>
        <View style={styles.infoItem}><Text style={styles.infoText}>• 每个数是前两个数之和</Text></View>
        <View style={styles.infoItem}><Text style={styles.infoText}>• 相邻两数之比趋近黄金比例 1.618</Text></View>
      </View>
    </ScrollView>
  );
};

规律说明区域显示斐波那契数列的数学规律。

四条规律

  1. 初始值:F(0) = 0, F(1) = 1
  2. 递推公式:F(n) = F(n-1) + F(n-2)
  3. 通俗解释:每个数是前两个数之和
  4. 黄金比例:相邻两数之比趋近 1.618

为什么显示规律?因为规律能帮助用户理解斐波那契数列。很多人知道斐波那契数列,但不知道具体规律。显示规律让用户学习数学知识,增加工具的教育价值。

为什么提到黄金比例?因为黄金比例是斐波那契数列的重要性质。相邻两数之比(比如 5/3 ≈ 1.667,8/5 = 1.6,13/8 = 1.625)越来越接近黄金比例 1.618。这个性质在自然界、艺术、建筑中广泛应用。

鸿蒙 ArkTS 对比:数列生成

@State count: string = '10'
@State sequence: number[] = []

generate() {
  const n = Math.min(parseInt(this.count) || 10, 50)
  const fib: number[] = [0, 1]
  for (let i = 2; i < n; i++) {
    fib.push(fib[i - 1] + fib[i - 2])
  }
  this.sequence = fib.slice(0, n)
}

build() {
  Column() {
    Text('斐波那契数列')
      .fontSize(28)
      .fontWeight(FontWeight.Bold)
    
    Row() {
      TextInput({ text: this.count, placeholder: '10' })
        .type(InputType.Number)
        .onChange((value: string) => {
          this.count = value
        })
      
      Button('🚀 生成')
        .onClick(() => {
          this.generate()
        })
    }
    
    Grid() {
      ForEach(this.sequence, (num: number, i: number) => {
        GridItem() {
          Column() {
            Text(`F(${i})`)
              .fontSize(10)
              .fontColor('#888')
            Text(num.toString())
              .fontSize(14)
              .fontWeight(FontWeight.Bold)
              .fontColor('#4A90D9')
          }
          .backgroundColor('#252550')
          .padding(10)
          .borderRadius(10)
        }
      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
  }
}

ArkTS 中的斐波那契数列生成逻辑完全一样。核心是循环计算,每次把前两个数相加。parseInt()Math.min()push()slice() 都是标准 JavaScript API,跨平台通用。

Grid 和 flexWrap 的区别

  • React Native 用 flexDirection: 'row'flexWrap: 'wrap' 实现网格布局
  • ArkTS 用 Grid 组件,columnsTemplate 定义列数

为什么 ArkTS 用 Grid?因为 ArkTS 提供了专门的网格组件,更符合声明式风格。React Native 没有网格组件,用 Flexbox 模拟。

样式定义

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#0f0f23', padding: 20 },
  header: { alignItems: 'center', marginBottom: 24 },
  headerIcon: { fontSize: 50, marginBottom: 8 },
  headerTitle: { fontSize: 28, fontWeight: '700', color: '#fff' },
  headerSubtitle: { fontSize: 14, color: '#888', marginTop: 4 },
  inputSection: { marginBottom: 20 },
  label: { fontSize: 14, color: '#888', marginBottom: 12 },
  inputRow: { flexDirection: 'row' },
  inputWrapper: { flex: 1, backgroundColor: '#1a1a3e', borderRadius: 12, marginRight: 12, borderWidth: 1, borderColor: '#3a3a6a' },
  input: { padding: 14, fontSize: 18, color: '#fff', textAlign: 'center' },
  btn: { backgroundColor: '#4A90D9', paddingHorizontal: 20, borderRadius: 12, justifyContent: 'center' },
  btnText: { color: '#fff', fontWeight: '700' },
  result: { backgroundColor: '#1a1a3e', padding: 16, borderRadius: 16, marginBottom: 20, borderWidth: 1, borderColor: '#3a3a6a' },
  resultTitle: { fontSize: 16, fontWeight: '600', marginBottom: 16, color: '#fff' },
  sequence: { flexDirection: 'row', flexWrap: 'wrap' },
  numItem: { backgroundColor: '#252550', padding: 10, margin: 4, borderRadius: 10, alignItems: 'center', minWidth: 65 },
  numIndex: { fontSize: 10, color: '#888' },
  numValue: { fontSize: 14, fontWeight: '700', color: '#4A90D9' },
  info: { backgroundColor: '#1a1a3e', padding: 16, borderRadius: 16, borderWidth: 1, borderColor: '#3a3a6a' },
  infoTitle: { fontSize: 16, fontWeight: '600', marginBottom: 16, color: '#fff' },
  infoItem: { marginBottom: 8 },
  infoText: { fontSize: 14, color: '#888' },
});

容器用深蓝黑色背景。输入框居中对齐。数列用网格布局,自动换行。数字卡片最小宽度 65,居中对齐。规律说明用列表布局,每条规律一行。

小结

这个斐波那契工具展示了数列生成和动画效果的实现。用循环计算斐波那契数列,每次把前两个数相加。限制最大值为 50,防止数字溢出。数字卡片用翻转动画依次出现,营造生成效果。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐