Flutter 作为 Google 的跨平台 UI 框架,用一套代码搞定 iOS、Android、Web------看起来很美好,但实际写起来,组件树动辄上百行,状态管理、路由、主题......一不留神就成一团乱麻。
这篇文章不讲基础语法,分享 7 个能让你写得更快、代码更干净的 Flutter 实战技巧。
1️⃣ 善用 Snippet,别手写样板代码
Flutter 的样板代码多到让人手酸。一个 StatefulWidget 光骨架就十几行。
内置模板已经够用:
- 输入 stless → 自动生成 StatelessWidget
- 输入 stful → 自动生成 StatefulWidget
更进一步,封装你自己的业务模板。比如一个带加载/错误状态的页面:
dart
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
bool loading = true;
@override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
try {
// 请求数据...
} catch (e) {
setState(() => error = e.toString());
} finally {
setState(() => loading = false);
}
}
@override
Widget build(BuildContext context) {
if (loading) return const Center(
child: CircularProgressIndicator());
if (error != null) return Center(
child: Text('出错啦:$error'));
return const YourContentWidget();
}
}
💡 Tip:把这个模板存成 snippet,每次新建页面 2 秒搞定骨架。
2️⃣ Extension 方法:让代码读起来像说话
Dart 的 Extension 是 Flutter 里最被低估的特性。封装得当,代码可读性飙升:
dart
// 导航简化
extension NavigationExt on BuildContext {
void push(Widget page) =>
Navigator.push(this,
MaterialPageRoute(builder: (_) => page));
}
// 边距简化
extension PaddingExt on Widget {
Widget pad(double all) =>
Padding(padding: EdgeInsets.all(all),
child: this);
}
// 时间友好显示
extension DateTimeExt on DateTime {
String timeAgo() {
final diff = DateTime.now().difference(this);
if (diff.inDays > 0) return '${diff.inDays}天前';
if (diff.inHours > 0) return '${diff.inHours}小时前';
return '刚刚';
}
}
调用起来清爽无比:
dart
context.push(DetailPage(id: 1)); // 导航
Text('Hello').pad(16); // 加边距
post.createdAt.timeAgo(); // "3小时前"
3️⃣ Widget 抽取:build 方法别超过 50 行
一个 build 方法塞满所有 UI,是 Flutter 项目变烂的头号原因。
铁律:一个 build 方法不超过 50 行。
| 代码量 | 怎么做 |
|---|---|
| 几行、只用一次 | Widget _buildXxx() 私有方法 |
| 有独立状态、或复用 | 独立 StatelessWidget |
| 超过 100 行、跨页面复用 | 单独文件 xxx_widget.dart |
抽取前 vs 抽取后,可维护性天壤之别。
4️⃣ 主题系统:一个 ThemeData 管全局
别到处写 Color(0xFF...) 和硬编码字号。主题系统统一管理:
dart
class AppTheme {
static ThemeData get light => ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF6750A4),
),
cardTheme: CardThemeData(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
);
}
然后用 Theme.of(context) 取值------改主题一处,全局生效。
5️⃣ Riverpod:编译安全的状态管理
状态管理方案眼花缭乱,Riverpod 是当下最推荐的选择------编译期安全、不依赖 BuildContext:
dart
// 简单状态
final counterProvider = StateProvider<int>((ref) => 0);
// 异步数据
final userProvider = FutureProvider<User>((ref) async {
return ref.read(apiProvider).fetchUser();
});
// 在 Widget 中使用
class CounterPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Text('点击了 $count 次');
}
}
🔑 关键区分:ref.watch() 监听变化自动重建,ref.read() 一次性读取不监听。
6️⃣ GoRouter:声明式路由不再头疼
Navigator 2.0 的 API 劝退了不少人。GoRouter 让路由清爽很多:
dart
final router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(path: '/',
builder: (_, __) => const HomePage()),
GoRoute(
path: '/detail/:id',
builder: (_, state) =>
DetailPage(
id: state.pathParameters['id']!),
),
],
);
支持深度链接、重定向、路由守卫------一个 package 搞定所有路由需求。
7️⃣ 组合技:一个标准页面模板
把上面的技巧串起来,一个标准的 Flutter 页面长这样:
dart
class DemoPage extends ConsumerStatefulWidget {
const DemoPage({super.key});
@override
ConsumerState<DemoPage> createState() =>
_DemoPageState();
}
class _DemoPageState extends ConsumerState<DemoPage> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final asyncData = ref.watch(dataProvider);
return Scaffold(
appBar: AppBar(
title: const Text('演示')),
body: asyncData.when(
loading: () => const Center(
child: CircularProgressIndicator()),
error: (e, _) => Center(
child: Text('出错了:$e')),
data: (items) => _buildList(items),
),
);
}
Widget _buildList(List<Item> items) =>
ListView.builder(
itemCount: items.length,
itemBuilder: (_, i) => Card(
child: ListTile(
title: Text(items[i].title),
subtitle: Text(items[i].desc),
),
),
);
}
📝 总结
FlutterSkills 的核心不是堆砌花哨的东西,而是用更少的代码做更多的事:
| 技巧 | 一句话 |
|---|---|
| Snippet | 别手写样板,2 秒出骨架 |
| Extension | 让代码读起来像自然语言 |
| Widget 抽取 | build 方法绝不超过 50 行 |
| 主题系统 | 一处改,全局生效 |
| Riverpod | 编译安全的轻量状态管理 |
| GoRouter | 声明式路由,告别 Navigator 2.0 |
这 7 个技巧组合起来,Flutter 开发的体验会顺畅很多。希望对你有帮助 🚀