Flutter for OpenHarmony:english_words 词汇随机生成神器,从“Startup Namer”到创意命名(3000字设计与实战)
还记得你学习 Flutter 的第一个官方教程 “Write your first Flutter app” 吗?这一切的背后,都依赖于一个极其小巧但功能强大的库 ——。它包含了最常用的 2534 个英语单词(名词、形容词、动词等),并提供了一套算法来随机生成看起来“像样”的词组(如对于开发者,它不仅仅是一个 Demo 工具,更是构建创意命名、随机昵称、验证码生成等功能的利器。让我们见识到了 Da
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

前言
还记得你学习 Flutter 的第一个官方教程 “Write your first Flutter app” 吗?
那个无限滚动的列表,每次滑动都会生成新的单词组合,点击心形图标即可收藏。
这一切的背后,都依赖于一个极其小巧但功能强大的库 —— english_words。
它包含了最常用的 2534 个英语单词(名词、形容词、动词等),并提供了一套算法来随机生成看起来“像样”的词组(如 StartupNamer)。
对于 OpenHarmony 开发者,它不仅仅是一个 Demo 工具,更是构建创意命名、随机昵称、验证码生成等功能的利器。
一、核心原理与数据结构
1.1 词库来源与优化
english_words 的数据并未直接存储为巨大的 JSON 文件,而是硬编码在 Dart 源码中(作为 List<String> 常量)。
这样做的好处是:
- 零 IO:无需解析 JSON,应用启动即加载。
- Tree Shaking:如果你只用了
adjectives,Dart 编译器会自动剔除未使用的nouns,减小包体积。 - 性能极高:直接内存访问。
1.2 组合生成算法 (WordPair)
核心类 WordPair 代表两个单词的组合(如 blue 和 sky -> BlueSky)。
它并不只是简单的字符串拼接,而是经过了精心挑选。
- PascalCase:
BlueSky - camelCase:
blueSky - snake_case:
blue_sky - lower case:
bluesky
库内部使用了高效的随机索引算法,确保生成的组合既具备随机性,又避免了一些生僻词组合。
二、核心 API 详解
2.1 生成单词组合
import 'package:english_words/english_words.dart';
void main() {
// 1. 生成 10 个随机组合
generateWordPairs().take(10).forEach((pair) {
print(pair.asPascalCase); // RedBicycle, ShinyApple...
});
// 2. 将组合转为不同格式
final pair = WordPair("super", "hero");
print(pair.asCamelCase); // superHero
print(pair.asSnakeCase); // super_hero
print(pair.asLowerCase); // superhero
print(pair.asUpperCase); // SUPERHERO
}

2.2 直接访问词库
有时我们需要单个名词或形容词。
// 获取所有名词 (约 2500 个)
print(nouns.take(5));
// 获取所有形容词 (约 1200 个)
print(adjectives.take(5));
// 检查是否包含某个单词
print(all.contains('flutter')); // true

2.3 音节与押韵 (Syllables & Rhymes)
这是库的高级功能。它不仅限于字符串,还包含简单的语音规则。
// 计算音节数
print(syllables('hello')); // 2 (hel-lo)
print(syllables('beautiful')); // 3 (beau-ti-ful)
// 简单的押韵检测 (Demo 级)
bool rhyme(String word1, String word2) {
// ... 基于后缀匹配 ...
}
三、OpenHarmony 平台适配实战
3.1 实战:构建鸿蒙版 Startup Namer
我们将经典 Flutter Demo 移植到鸿蒙,并增加持久化功能。
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
// 需配合 shared_preferences 适配
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Ohos Name Generator',
home: RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
_RandomWordsState createState() => _RandomWordsState();
}
class _RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _saved = <WordPair>{};
void initState() {
super.initState();
_loadSaved();
}
// 从本地存储加载收藏
Future<void> _loadSaved() async {
final prefs = await SharedPreferences.getInstance();
final List<String> savedStrings = prefs.getStringList('saved_names') ?? [];
setState(() {
_saved.addAll(savedStrings.map((s) {
var parts = s.split(/(?=[A-Z])/); // 简单拆分 PascalCase
return WordPair(parts[0].toLowerCase(), parts[1].toLowerCase());
}));
});
}
void _pushSaved() {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) {
final tiles = _saved.map(
(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: TextStyle(fontSize: 18.0),
),
);
},
);
final divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return Scaffold(
appBar: AppBar(title: Text('Saved Suggestions')),
body: ListView(children: divided),
);
},
),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Startup Name Generator'),
actions: [
IconButton(icon: Icon(Icons.list), onPressed: _pushSaved),
],
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return ListView.builder(
padding: EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
},
);
}
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return ListTile(
title: Text(
pair.asPascalCase,
style: TextStyle(fontSize: 18.0),
),
trailing: Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
// 实时保存
SharedPreferences.getInstance().then((prefs) {
prefs.setStringList(
'saved_names',
_saved.map((p) => p.asPascalCase).toList()
);
});
},
);
}
}

3.2 进阶:随机昵称生成器
在社交 App 中,用户不想填昵称时,我们可以给一个默认值。
void _generate() {
// 💡 组合策略:形容词 + 名词 + 随机两位数
// 注意:adjectives 和 nouns 是不可变列表,需要先复制为可变列表再 shuffle
final adjList = List<String>.from(adjectives)..shuffle();
final nounList = List<String>.from(nouns)..shuffle();
final adj = adjList.first;
final noun = nounList.first;
final suffix = Random().nextInt(99).toString().padLeft(2, '0');
setState(() {
_nickname = '${adj.capitalize()}${noun.capitalize()}$suffix';
});
}

四、性能与包体积考量
4.1 包体积 (Size)
english_words 包含约 4000 个单词。如果不 Treeshake,可能会增加约 50KB 的包体积。这在现代 App 中完全可以忽略不计。
但如果你正在构建极简的 Instant App(原子服务),可以考虑只 fork 下来这部分代码,手动删减不用的单词。
4.2 启动时间
由于是 const List,加载速度极快,不会阻塞 UI 线程。在鸿蒙设备上测试,从 main() 到第一帧渲染完全无感知。
五、总结
english_words 让我们见识到了 Dart 语言处理基础数据的优雅。它没有复杂的逻辑,却通过简单的组合产生了无限的创意。
对于 OpenHarmony 开发者:
- 教学工具:它是演示 ListView, State, Navigation 最好的例子。
- 创意工具:不仅是 Startup Namer,任何需要随机文本的地方(测试数据、占位符、默认昵称),它都是首选。
更多推荐



所有评论(0)