React Native for OpenHarmony 实战:斐波那契实现
本文介绍了使用React Native实现斐波那契数列生成工具的关键实现细节。该工具支持生成指定数量的斐波那契数,并具有动画效果。状态设计包含数量输入(字符串类型)、生成的数列数组以及按钮和数字卡片的动画值。生成函数实现了按钮点击动画、数值解析(限制最大值50)以及斐波那契数列的计算逻辑。界面渲染包含头部标题、数字输入框和生成按钮,数列显示区域会以动画形式依次呈现每个数字。通过延迟动画和弹簧效果,

今天我们用 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:数字卡片的动画数组,每个数字一个动画值
为什么数量用字符串?因为 TextInput 的 value 必须是字符串。如果用数字,需要在 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),默认 10Math.min(..., 50):限制最大值为 50,防止生成太多数字
初始化数列:[0, 1] 是斐波那契数列的前两个数。
循环生成:从索引 2 开始,每次把前两个数相加,加入数组。
fib[i - 1]:前一个数fib[i - 2]:前两个数fib[i - 1] + fib[i - 2]:当前数
为什么限制最大值为 50?因为斐波那契数增长很快,第 50 个数已经是 12586269025(125 亿)。生成太多数字会导致:
- 界面卡顿(太多卡片)
- 数字溢出(JavaScript 的
Number类型最大安全整数是 2^53 - 1) - 用户体验差(滚动太长)
举例:生成前 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>
);
};
规律说明区域显示斐波那契数列的数学规律。
四条规律:
- 初始值:
F(0) = 0, F(1) = 1 - 递推公式:
F(n) = F(n-1) + F(n-2) - 通俗解释:每个数是前两个数之和
- 黄金比例:相邻两数之比趋近 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:数字卡片的动画数组,每个数字一个动画值
为什么数量用字符串?因为 TextInput 的 value 必须是字符串。如果用数字,需要在 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),默认 10Math.min(..., 50):限制最大值为 50,防止生成太多数字
初始化数列:[0, 1] 是斐波那契数列的前两个数。
循环生成:从索引 2 开始,每次把前两个数相加,加入数组。
fib[i - 1]:前一个数fib[i - 2]:前两个数fib[i - 1] + fib[i - 2]:当前数
为什么限制最大值为 50?因为斐波那契数增长很快,第 50 个数已经是 12586269025(125 亿)。生成太多数字会导致:
- 界面卡顿(太多卡片)
- 数字溢出(JavaScript 的
Number类型最大安全整数是 2^53 - 1) - 用户体验差(滚动太长)
举例:生成前 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>
);
};
规律说明区域显示斐波那契数列的数学规律。
四条规律:
- 初始值:
F(0) = 0, F(1) = 1 - 递推公式:
F(n) = F(n-1) + F(n-2) - 通俗解释:每个数是前两个数之和
- 黄金比例:相邻两数之比趋近 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
更多推荐


所有评论(0)