Flutter热重载插件flutter_reload的使用
Flutter热重载插件flutter_reload的使用
flutter_reload
插件简化了错误处理,通过管理底层错误,让开发者可以专注于业务逻辑。
为什么使用 flutter_reload
我们喜欢并通常选择一种状态管理机制作为我们的基础架构。在许多情况下,例如使用网络API时,每个视图都需要一个“何时”条件来处理异常。
flutter_reload
尝试创建一个轻量级层来处理所有常见的错误情况。通过额外的保护措施 guard
,我们不再需要为每个UI和模型管理每个异常情况,如网络错误、存储错误、编程异常等。我们称之为无异常意识的愉快开发体验。:D :)
带有异常意识的UI概念
Widget build(BuildContext context) {
switch (result) {
case loading:
return Text('Loading view data...');
case error:
return Text('Load data failed.');
case data(data):
return Text('Yes!! Here is the $data!!');
}
}
无异常意识的UI概念
Widget build(BuildContext context) {
return GuardView(
builder: (context) {
return Text('Yes!! Here is the ${result.data}!!');
}
);
}
带有异常意识的Model概念
Future<void> createTodo(Todo todo) {
try {
state = Result.loading();
final data = await todoService.createTodo();
state = Result.success(Todo.fromJson(data));
} catch (ex) {
if (ex is NetworkException) {
state = Result.error(ex);
} else if ...
}
}
无异常意识的Model概念
Future<void> createTodo(Todo todo) {
await guard(() {
final data = await todoService.createTodo();
state = Result.success(Todo.fromJson(data));
});
}
安装
请按照以下步骤安装此包:
-
在项目的
pubspec.yaml
文件中添加依赖:dependencies: flutter_reload: ^版本号
-
运行
flutter pub get
更新依赖。
安装完成后,你可以通过以下三个主要步骤轻松集成 flutter_reload
:
第一步:初始化配置
void main() {
ReloadConfiguration.init(
abnormalStateBuilder: globalAbnormalStateBuilder,
exceptionHandle: globalExceptionHandle,
);
runApp(const MyApp());
}
Widget? globalAbnormalStateBuilder(BuildContext context, GuardState guardState,
DataSupplier<FutureOr<void>> dataReloader) {
switch (guardState) {
case InitGuardState():
return const Center(child: CircularProgressIndicator.adaptive());
case OfflineGuardState():
return const Center(child: Text('Offline...'));
case ErrorGuardState<CustomException>(cause: CustomException cause):
return Center(child: Text('Error: ${cause.message}'));
case ErrorGuardState<Exception>(cause: var cause):
return Center(child: Text('Error: $cause'));
default:
return null;
}
}
void globalExceptionHandle(
exception,
stackTrace, {
GuardStateController? guardStateController,
GuardExceptionHandleResult Function(dynamic, dynamic)? onError,
required bool silent,
}) {
final errorHandlerResult = onError?.call(exception, stackTrace) ??
GuardExceptionHandleResult.byDefault;
if (guardStateController != null &&
guardStateController.value is InitGuardState) {
// TODO: 记录意外错误
guardStateController.value = ErrorGuardState<Exception>(cause: exception);
} else {
if (errorHandlerResult == GuardExceptionHandleResult.mute) {
return;
} else {
// TODO: 记录意外错误
ScaffoldMessenger.of(rootContext!)
.showSnackBar(SnackBar(content: Text('$exception')));
}
}
}
第二步:支持UI模型的重新加载生命周期
class MyViewModel extends GuardViewModel {
final randomWords = <String>[];
MyViewModel() : super(GuardState.init);
@override
FutureOr<void> reload() async {
await guardReload(() async {
randomWords..clear()..addAll(await myNetworkService.getRandomWordsFromServer());
notifyListeners();
});
}
}
第三步:使用 GuardView()
构建UI
@override
Widget build(BuildContext context) {
return GuardView(
model: myViewModel,
builder: (context) {
return ListenableWidget(
model: myViewModel,
builder: (context) {
return ListView.separated(
itemBuilder: (BuildContext context, int index) {
final rowData = myViewModel.randomWords[index];
return ListTile(
key: ValueKey(rowData),
title: Text(rowData),
);
},
separatorBuilder: (context, index) => const Divider(),
itemCount: myViewModel.randomWords.length,
);
},
);
},
);
}
示例
以下是几个示例项目:
- 新闻: 使用
ChangeNotifier
作为状态管理的 HackNews 演示。 - 新闻 Riverpod: 使用 Riverpod 作为状态管理的 HackNews 演示。
- 待办事项: 使用
ChangeNotifier
作为状态管理的常见待办事项应用演示。
架构
生命周期
LLM友好的框架
合并所有 Dart 文件
在Mac环境中合并所有 Dart 文件(核心+示例)到单个上下文中:
find ./packages/flutter_reload ./examples/news -name "*.dart" -print0 | xargs -0 cat > ~/Downloads/flutter_reload_source
此外,你可以将任何示例添加到 ./examples/news
中。
添加上下文到你的LLM引用中
[FLUTTER_RELAOD_SOURCE]
帮助编写一个带有 flutter_reload
的待办事项应用。你需要实现以下需求:
- 实现模型和UI的TODO CRUD操作。
- 支持持久化以保存模型的待办事项。
更多关于Flutter热重载插件flutter_reload的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter热重载插件flutter_reload的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于Flutter热重载插件flutter_reload
的使用,下面是一个简单的代码案例来展示如何集成和使用这个插件。
首先,你需要在你的pubspec.yaml
文件中添加flutter_reload
依赖:
dependencies:
flutter:
sdk: flutter
flutter_reload: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来获取依赖。
接下来,你可以在你的Flutter应用中集成flutter_reload
插件。以下是一个简单的例子:
- 创建主应用文件(
main.dart
):
import 'package:flutter/material.dart';
import 'package:flutter_reload/flutter_reload.dart';
void main() {
// 初始化 FlutterReload
FlutterReload.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
// 监听热重载事件
@override
void initState() {
super.initState();
FlutterReload.addListener(() {
print("Flutter app reloaded!");
// 你可以在这里添加任何需要在热重载时执行的代码
});
}
@override
void dispose() {
// 移除监听器
FlutterReload.removeListener(() {});
super.dispose();
}
}
- 运行应用:
使用flutter run
命令运行你的应用。在开发过程中,当你对代码进行修改并保存后,Flutter会自动触发热重载。
- 热重载事件监听:
在上述代码中,我们添加了FlutterReload.addListener
来监听热重载事件。每次热重载发生时,控制台会打印出"Flutter app reloaded!"。你可以在这个回调中添加任何你需要在热重载时执行的代码,比如重置状态、清理资源等。
- 移除监听器:
在dispose
方法中,我们移除了监听器。这是一个良好的实践,以确保在组件被销毁时不会留下任何悬挂的引用。
通过上述步骤,你就可以在你的Flutter应用中集成并使用flutter_reload
插件来监听热重载事件。请注意,flutter_reload
插件的具体用法可能会根据版本有所不同,请参考其官方文档和示例代码以获取最新和详细的信息。