ワンクリックで
flutter-state-management
Flutter 状态管理最佳实践。Invoke when: 1) 需要管理应用状态 2) 实现用户登录状态 3) 主题切换 4) 数据共享 between widgets
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Flutter 状态管理最佳实践。Invoke when: 1) 需要管理应用状态 2) 实现用户登录状态 3) 主题切换 4) 数据共享 between widgets
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Create or update minimal AGENTS.md files in the repository root and nested module directories using progressive disclosure. Works across heterogeneous projects without assuming any fixed agent folder structure.
Code review excellence guidelines and best practices. Invoke when reviewing code, ensuring code quality, identifying bugs, improving performance, and maintaining code standards.
Complete guide for using drift database library in Dart applications (CLI, server-side, non-Flutter). Use when building Dart apps that need local SQLite database storage or PostgreSQL connection with type-safe queries, reactive streams, migrations, and efficient CRUD operations. Includes setup with sqlite3 package, PostgreSQL support with drift_postgres, connection pooling, and server-side patterns.
Build adaptive and responsive Flutter UIs that work beautifully across all platforms and screen sizes. Use when creating Flutter apps that need to adapt layouts based on screen size, support multiple platforms including mobile tablet desktop and web, handle different input devices like touch mouse and keyboard, implement responsive navigation patterns, optimize for large screens and foldables, or use Capability and Policy patterns for platform-specific behavior.
Comprehensive guide for implementing animations in Flutter. Use when adding motion and visual effects to Flutter apps: implicit animations (AnimatedContainer, AnimatedOpacity, TweenAnimationBuilder), explicit animations (AnimationController, Tween, AnimatedWidget/AnimatedBuilder), hero animations (shared element transitions), staggered animations (sequential/overlapping), and physics-based animations. Includes workflow for choosing the right animation type, implementation patterns, and best practices for performance and user experience.
Flutter HTTP API 集成规范。Invoke when: 1) 添加新的 API 接口 2) 处理网络请求 3) 实现数据缓存 4) 处理请求错误
| name | flutter-state-management |
| description | Flutter 状态管理最佳实践。Invoke when: 1) 需要管理应用状态 2) 实现用户登录状态 3) 主题切换 4) 数据共享 between widgets |
本项目使用 Provider + GetX 混合模式:
lib/utils/store/
├── app/
│ └── appState.dart # 应用全局状态
├── home/
│ └── color_notifier.dart # 首页颜色状态
├── ranking/
│ └── ranking_background_notifier.dart # 排行榜背景
├── theme/
│ └── theme.dart # 主题状态
└── user/
└── user.dart # 用户状态
import 'package:flutter/material.dart';
import 'package:flutter_app/entity/user_info_entity.dart';
class UserStore extends ChangeNotifier {
UserInfoEntity? _userInfo;
bool _isLogin = false;
UserInfoEntity? get userInfo => _userInfo;
bool get isLogin => _isLogin;
void setUserInfo(UserInfoEntity userInfo) {
_userInfo = userInfo;
_isLogin = true;
notifyListeners();
}
void logout() {
_userInfo = null;
_isLogin = false;
notifyListeners();
}
}
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserStore()),
ChangeNotifierProvider(create: (_) => ThemeStore()),
ChangeNotifierProvider(create: (_) => AppState()),
],
child: MyApp(),
),
);
}
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<UserStore>(
builder: (context, userStore, child) {
return Scaffold(
body: userStore.isLogin
? Text('欢迎, ${userStore.userInfo?.nickname}')
: LoginButton(),
);
},
);
}
}
// 只监听特定字段
class UserAvatar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Selector<UserStore, String?>(
selector: (store) => store.userInfo?.avatar,
builder: (context, avatar, child) {
return CircleAvatar(
backgroundImage: avatar != null ? NetworkImage(avatar) : null,
);
},
);
}
}
// 定义路由
class AppPages {
static final routes = [
GetPage(name: '/home', page: () => HomePage()),
GetPage(name: '/detail/:id', page: () => VideoDetailPage()),
GetPage(name: '/login', page: () => LoginPage()),
];
}
// 跳转页面
Get.toNamed('/detail/123');
Get.offNamed('/home'); // 清除之前的路由
Get.back(); // 返回
class CountController extends GetxController {
var count = 0.obs;
void increment() {
count++;
}
}
// 使用
class CounterPage extends StatelessWidget {
final controller = Get.put(CountController());
@override
Widget build(BuildContext context) {
return Obx(() => Text('Count: ${controller.count}'));
}
}
| 状态类型 | 管理方式 | 示例 |
|---|---|---|
| 应用级状态 | Provider | 用户信息、登录状态 |
| 页面级状态 | StatefulWidget | 表单输入、加载状态 |
| 临时状态 | GetX | 计数器、开关状态 |
| 共享状态 | Provider | 主题、语言设置 |
// ❌ 错误:所有状态都用 Provider
// ✅ 正确:简单状态用 StatefulWidget
class SearchPage extends StatefulWidget {
@override
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
String _keyword = ''; // 页面级状态,不需要 Provider
@override
Widget build(BuildContext context) {
return TextField(
onChanged: (value) => setState(() => _keyword = value),
);
}
}
class VideoDetailPage extends StatefulWidget {
final int videoId;
VideoDetailPage({required this.videoId});
@override
State<VideoDetailPage> createState() => _VideoDetailPageState();
}
class _VideoDetailPageState extends State<VideoDetailPage> {
late Future<VideoDetailEntity> _videoFuture;
@override
void initState() {
super.initState();
_videoFuture = VideoApi.getDetail(widget.videoId);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _videoFuture,
builder: (context, snapshot) {
// 处理不同状态
},
);
}
}
class AuthWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<UserStore>(
builder: (context, userStore, child) {
if (userStore.isLogin) {
return HomePage();
}
return LoginPage();
},
);
}
}
class ThemeStore extends ChangeNotifier {
ThemeMode _themeMode = ThemeMode.system;
ThemeMode get themeMode => _themeMode;
void setThemeMode(ThemeMode mode) {
_themeMode = mode;
notifyListeners();
}
bool get isDarkMode => _themeMode == ThemeMode.dark;
}
// 在 MaterialApp 中使用
MaterialApp(
themeMode: context.watch<ThemeStore>().themeMode,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
)
class VideoCacheStore extends ChangeNotifier {
final Map<int, VideoDetailEntity> _cache = {};
VideoDetailEntity? getVideo(int id) => _cache[id];
void cacheVideo(VideoDetailEntity video) {
_cache[video.id] = video;
notifyListeners();
}
}