flutter-dev by bogdanustyak/flutter-expert-skill
npx skills add https://github.com/bogdanustyak/flutter-expert-skill --skill flutter-dev遵循官方 Flutter 团队最佳实践的 Flutter 和 Dart 开发专家指导。
StatelessWidget)lib/main.dart 为入口点生成代码时:
dart format 工具保持一致的格式dart fix 工具自动修复常见错误Expert guidance for Flutter and Dart development following official Flutter team best practices.
StatelessWidget when possible)lib/main.dart as entry pointWhen generating code:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
PascalCasecamelCasesnake_casetry-catch 块async/await 并配合稳健的错误处理dartdoc 注释/// 作为文档注释! 操作符,除非值保证非空switch 语句/表达式(不需要 break)Futures、async、awaitStreamsStatelessWidget)是不可变的Widget 类,而不是返回小部件的私有辅助方法build() 方法分解为更小、可重用的私有 Widget 类const 构造函数以减少重建ListView.builder 或 SliverListcompute() 在单独的 isolate 中运行昂贵的计算(例如,JSON 解析)build() 方法中进行昂贵的操作(网络调用、复杂计算)build() 方法中使用 const 构造函数以最小化重建LayoutBuilder 或 MediaQuery 实现响应式 UI除非明确要求第三方,否则优先使用 Flutter 的内置解决方案:
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
ValueListenableBuilder<int>(
valueListenable: _counter,
builder: (context, value, child) => Text('Count: $value'),
);
2. ChangeNotifier + ListenableBuilder - 跨小部件的复杂/共享状态
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
ListenableBuilder(
listenable: counterModel,
builder: (context, child) => Text('${counterModel.count}'),
);
3. Streams + StreamBuilder - 异步事件序列 4. Futures + FutureBuilder - 单个异步操作
使用 go_router 进行声明式导航、深度链接和 Web 支持:
// 添加依赖
flutter pub add go_router
// 配置路由器
final GoRouter _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomeScreen(),
routes: [
GoRoute(
path: 'details/:id',
builder: (context, state) {
final String id = state.pathParameters['id']!;
return DetailScreen(id: id);
},
),
],
),
],
);
// 在 MaterialApp 中使用
MaterialApp.router(routerConfig: _router);
redirect 属性用于不需要深度链接的短暂屏幕(对话框、临时视图):
Navigator.push(context, MaterialPageRoute(builder: (context) => DetailsScreen()));
Navigator.pop(context);
flutter pub add <package_name>flutter pub add dev:<package_name>flutter pub add override:<package_name>:1.0.0dart pub remove <package_name>使用 json_serializable 和 json_annotation:
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(fieldRename: FieldRename.snake)
class User {
final String firstName;
final String lastName;
User({required this.firstName, required this.lastName});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
build_runner 是开发依赖项dart run build_runner build --delete-conflicting-outputs使用 dart:developer 进行结构化日志记录:
import 'dart:developer' as developer;
// 简单消息
developer.log('用户登录成功。');
// 结构化错误日志记录
try {
// 代码
} catch (e, s) {
developer.log(
'获取数据失败',
name: 'myapp.network',
level: 1000, // SEVERE
error: e,
stackTrace: s,
);
}
使用 ColorScheme.fromSeed() 获取和谐的调色板:
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.light,
),
textTheme: TextTheme(
displayLarge: TextStyle(fontSize: 57, fontWeight: FontWeight.bold),
bodyMedium: TextStyle(fontSize: 14, height: 1.4),
),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.dark,
),
),
themeMode: ThemeMode.system,
);
用于标准 ThemeData 之外的自定义设计标记:
@immutable
class MyColors extends ThemeExtension<MyColors> {
const MyColors({required this.success, required this.danger});
final Color? success;
final Color? danger;
@override
ThemeExtension<MyColors> copyWith({Color? success, Color? danger}) {
return MyColors(success: success ?? this.success, danger: danger ?? this.danger);
}
@override
ThemeExtension<MyColors> lerp(ThemeExtension<MyColors>? other, double t) {
if (other is! MyColors) return this;
return MyColors(
success: Color.lerp(success, other.success, t),
danger: Color.lerp(danger, other.danger, t),
);
}
}
// 在 ThemeData 中注册
theme: ThemeData(
extensions: [MyColors(success: Colors.green, danger: Colors.red)],
),
// 在小部件中使用
Container(color: Theme.of(context).extension<MyColors>()!.success)
使用 google_fonts 包获取自定义字体:
flutter pub add google_fonts
final TextTheme appTextTheme = TextTheme(
displayLarge: GoogleFonts.oswald(fontSize: 57, fontWeight: FontWeight.bold),
titleLarge: GoogleFonts.roboto(fontSize: 22, fontWeight: FontWeight.w500),
bodyMedium: GoogleFonts.openSans(fontSize: 14),
);
在 pubspec.yaml 中声明:
flutter:
uses-material-design: true
assets:
- assets/images/
// 本地图片
Image.asset('assets/images/placeholder.png')
// 网络图片(始终包含错误处理)
Image.network(
'https://example.com/image.png',
loadingBuilder: (context, child, progress) {
if (progress == null) return child;
return Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) => Icon(Icons.error),
)
使用 OverlayPortal 实现位于所有内容之上的 UI 元素:
final _controller = OverlayPortalController();
OverlayPortal(
controller: _controller,
overlayChildBuilder: (context) => Positioned(
top: 50,
left: 10,
child: Card(child: Text('覆盖层内容')),
),
child: ElevatedButton(
onPressed: _controller.toggle,
child: Text('切换'),
),
)
package:test 用于领域逻辑、数据层、状态管理package:flutter_test 用于 UI 组件package:integration_test 用于端到端流程package:checks 以获得更具表现力的断言mockito 或 mocktailfile、process、platform 包进行依赖注入flutter test
Semantics 小部件提供清晰、描述性的标签在 analysis_options.yaml 中包含:
include: package:flutter_lints/flutter.yaml
linter:
rules:
# 在此处添加额外的 lint 规则
有关详细模式和示例,请参阅:
references/navigation_patterns.md - 使用 GoRouter 的高级导航模式references/state_patterns.md - 全面的状态管理示例references/theme_patterns.md - 高级主题和样式模式每周安装量
83
仓库
首次出现
2026年1月23日
安全审计
安装于
gemini-cli71
opencode69
codex63
cursor59
github-copilot58
claude-code57
dart formatdart fix tool to automatically fix common errorsPascalCase for classescamelCase for members/variables/functions/enumssnake_case for filestry-catch blocks with appropriate exception typesasync/await usage with robust error handlingdartdoc comments to all public APIs (classes, constructors, methods, top-level functions)/// for doc comments! operator unless value is guaranteed non-nullswitch statements/expressions (no break needed)Futures, async, await for single asynchronous operationsStreams for sequences of asynchronous eventsStatelessWidget) are immutableWidget classes instead of private helper methods returning widgetsbuild() methods into smaller, reusable private Widget classesconst constructors whenever possible to reduce rebuildsListView.builder or SliverList for long lists (lazy-loaded)compute() to run expensive calculations in separate isolate (e.g., JSON parsing)build() methodsconst constructors in build() methods to minimize rebuildsLayoutBuilder or MediaQuery for responsive UIsPrefer Flutter's built-in solutions unless third-party explicitly requested:
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
ValueListenableBuilder<int>(
valueListenable: _counter,
builder: (context, value, child) => Text('Count: $value'),
);
2. ChangeNotifier + ListenableBuilder - Complex/shared state across widgets
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
ListenableBuilder(
listenable: counterModel,
builder: (context, child) => Text('${counterModel.count}'),
);
3. Streams + StreamBuilder - Sequences of asynchronous events 4. Futures + FutureBuilder - Single async operations
Use go_router for declarative navigation, deep linking, and web support:
// Add dependency
flutter pub add go_router
// Configure router
final GoRouter _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomeScreen(),
routes: [
GoRoute(
path: 'details/:id',
builder: (context, state) {
final String id = state.pathParameters['id']!;
return DetailScreen(id: id);
},
),
],
),
],
);
// Use in MaterialApp
MaterialApp.router(routerConfig: _router);
redirect property for authentication flowsUse for short-lived screens not needing deep links (dialogs, temporary views):
Navigator.push(context, MaterialPageRoute(builder: (context) => DetailsScreen()));
Navigator.pop(context);
flutter pub add <package_name>flutter pub add dev:<package_name>flutter pub add override:<package_name>:1.0.0dart pub remove <package_name>Use json_serializable and json_annotation:
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(fieldRename: FieldRename.snake)
class User {
final String firstName;
final String lastName;
User({required this.firstName, required this.lastName});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
build_runner is dev dependencydart run build_runner build --delete-conflicting-outputsUse dart:developer for structured logging:
import 'dart:developer' as developer;
// Simple messages
developer.log('User logged in successfully.');
// Structured error logging
try {
// code
} catch (e, s) {
developer.log(
'Failed to fetch data',
name: 'myapp.network',
level: 1000, // SEVERE
error: e,
stackTrace: s,
);
}
Use ColorScheme.fromSeed() for harmonious palettes:
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.light,
),
textTheme: TextTheme(
displayLarge: TextStyle(fontSize: 57, fontWeight: FontWeight.bold),
bodyMedium: TextStyle(fontSize: 14, height: 1.4),
),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.dark,
),
),
themeMode: ThemeMode.system,
);
For custom design tokens beyond standard ThemeData:
@immutable
class MyColors extends ThemeExtension<MyColors> {
const MyColors({required this.success, required this.danger});
final Color? success;
final Color? danger;
@override
ThemeExtension<MyColors> copyWith({Color? success, Color? danger}) {
return MyColors(success: success ?? this.success, danger: danger ?? this.danger);
}
@override
ThemeExtension<MyColors> lerp(ThemeExtension<MyColors>? other, double t) {
if (other is! MyColors) return this;
return MyColors(
success: Color.lerp(success, other.success, t),
danger: Color.lerp(danger, other.danger, t),
);
}
}
// Register in ThemeData
theme: ThemeData(
extensions: [MyColors(success: Colors.green, danger: Colors.red)],
),
// Use in widgets
Container(color: Theme.of(context).extension<MyColors>()!.success)
Use google_fonts package for custom fonts:
flutter pub add google_fonts
final TextTheme appTextTheme = TextTheme(
displayLarge: GoogleFonts.oswald(fontSize: 57, fontWeight: FontWeight.bold),
titleLarge: GoogleFonts.roboto(fontSize: 22, fontWeight: FontWeight.w500),
bodyMedium: GoogleFonts.openSans(fontSize: 14),
);
Declare in pubspec.yaml:
flutter:
uses-material-design: true
assets:
- assets/images/
// Local images
Image.asset('assets/images/placeholder.png')
// Network images (always include error handling)
Image.network(
'https://example.com/image.png',
loadingBuilder: (context, child, progress) {
if (progress == null) return child;
return Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) => Icon(Icons.error),
)
Use OverlayPortal for UI elements on top of everything:
final _controller = OverlayPortalController();
OverlayPortal(
controller: _controller,
overlayChildBuilder: (context) => Positioned(
top: 50,
left: 10,
child: Card(child: Text('Overlay content')),
),
child: ElevatedButton(
onPressed: _controller.toggle,
child: Text('Toggle'),
),
)
package:test for domain logic, data layer, state managementpackage:flutter_test for UI componentspackage:integration_test for end-to-end flowspackage:checks for more expressive assertionsmockito or mocktailfile, process, platform packages for dependency injectionflutter test
Semantics widget for clear, descriptive labelsInclude in analysis_options.yaml:
include: package:flutter_lints/flutter.yaml
linter:
rules:
# Add additional lint rules here
For detailed patterns and examples, see:
references/navigation_patterns.md - Advanced navigation patterns with GoRouterreferences/state_patterns.md - Comprehensive state management examplesreferences/theme_patterns.md - Advanced theming and styling patternsWeekly Installs
83
Repository
First Seen
Jan 23, 2026
Security Audits
Installed on
gemini-cli71
opencode69
codex63
cursor59
github-copilot58
claude-code57
Flutter 主屏幕小组件开发指南:iOS/Android 原生小组件集成与数据通信
3,700 周安装