Flutter依赖注入与状态管理插件katana_scoped的使用
Flutter依赖注入与状态管理插件katana_scoped的使用
介绍
Flutter的状态分为以下两类,如官方描述:
- Ephemeral state:在单个widget内封闭的状态。例如导航栏的当前位置、文本表单的当前输入状态等。
- App state:在应用内共享的状态。用于多个Widgets之间,例如从数据库检索的数据、登录状态、用户偏好设置等。
katana_scoped
是一个Flutter的状态管理插件,它通过显式地划分这些状态类型来简化状态管理。
安装
首先,您需要导入 katana_scoped
包:
flutter pub add katana_scoped
实现
前期准备
在应用程序根目录附近创建一个 AppRef
并放置 AppScoped
小部件。
// main.dart
import 'package:flutter/material.dart';
import 'package:katana_scoped/katana_scoped.dart';
void main() {
runApp(const MyApp());
}
final appRef = AppRef();
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return AppScoped(
appRef: appRef,
child: MaterialApp(
home: const CounterPage(),
title: "Flutter Demo",
theme: ThemeData(
primarySwatch: Colors.blue,
),
),
);
}
}
创建页面
创建页面时,实现一个扩展 PageScopedWidget
的小部件。
// counter_page.dart
import 'package:flutter/material.dart';
import 'package:katana_scoped/katana_scoped.dart';
class CounterPage extends PageScopedWidget {
const CounterPage({super.key});
[@override](/user/override)
Widget build(BuildContext context, PageRef ref) {
final counter = ref.page.watch((ref) => ValueNotifier(0));
return Scaffold(
appBar: AppBar(
title: const Text("Test App"),
),
body: Center(
child: Text("${counter.value}"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
counter.value++;
},
child: const Icon(Icons.add),
),
);
}
}
创建小部件
在页面下可以放置任何小部件,如 StatelessWidget
或 StatefulWidget
,但如果您想管理状态,可以通过创建 ScopedWidget
来实现。
// scoped_test_page.dart
import 'package:flutter/material.dart';
import 'package:katana_scoped/katana_scoped.dart';
class ScopedTestPage extends PageScopedWidget {
const ScopedTestPage({super.key});
[@override](/user/override)
Widget build(BuildContext context, PageRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text("Test App"),
),
body: ScopedTestContent(),
);
}
}
class ScopedTestContent extends ScopedWidget {
const ScopedTestContent({
super.key,
});
[@override](/user/override)
Widget build(BuildContext context, WidgetRef ref) {
final widget = ref.widget.watch((ref) => ValueNotifier(0));
final page = ref.page.watch((ref) => ValueNotifier(0));
final app = ref.app.watch((ref) => ValueNotifier(0));
return Column(
children: [
ListTile(
title: Text(app.value.toString()),
onTap: () {
app.value++;
},
),
ListTile(
title: Text(page.value.toString()),
onTap: () {
page.value++;
},
),
ListTile(
title: Text(widget.value.toString()),
onTap: () {
widget.value++;
},
),
],
);
}
}
使用示例代码
以下是完整的示例代码,展示了如何使用 katana_scoped
管理状态和依赖注入。
// main.dart
import 'package:flutter/material.dart';
import 'package:katana_scoped/katana_scoped.dart';
void main() {
runApp(const MyApp());
}
final appRef = AppRef();
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return AppScoped(
appRef: appRef,
child: MaterialApp(
home: const CounterPage(),
title: "Flutter Demo",
theme: ThemeData(
primarySwatch: Colors.blue,
),
),
);
}
}
final valueNotifierQuery =
ChangeNotifierAppScopedQueryFamily<ValueNotifier<int>, int>(
(ref, p) => ValueNotifier(p),
);
class CounterPage extends PageScopedWidget {
const CounterPage({super.key});
[@override](/user/override)
Widget build(BuildContext context, PageRef ref) {
final counter = ref.app.query(valueNotifierQuery(100));
return Scaffold(
appBar: AppBar(title: const Text("App Demo")),
body: Center(
child: Text("${counter.value}"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
counter.value++;
},
child: const Icon(Icons.add),
),
);
}
}
更多关于Flutter依赖注入与状态管理插件katana_scoped的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter依赖注入与状态管理插件katana_scoped的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用katana_scoped
插件进行依赖注入与状态管理的代码示例。katana_scoped
是一个轻量级的依赖注入和状态管理库,它允许你在Flutter应用中更轻松地管理依赖关系和状态。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加katana_scoped
依赖:
dependencies:
flutter:
sdk: flutter
katana_scoped: ^最新版本号 # 请替换为实际发布的最新版本号
然后运行flutter pub get
来安装依赖。
2. 设置依赖注入容器
创建一个文件,比如app_container.dart
,来设置你的依赖注入容器:
import 'package:katana_scoped/katana_scoped.dart';
import 'package:flutter/material.dart';
// 定义一个简单的服务类
class MyService {
String getMessage() {
return 'Hello from MyService!';
}
}
// 创建依赖注入容器
final container = Container();
void setupLocator() {
container.registerSingleton<MyService>(() => MyService());
}
3. 在应用入口初始化依赖注入
在你的main.dart
文件中,初始化依赖注入容器:
import 'package:flutter/material.dart';
import 'app_container.dart';
void main() {
// 初始化依赖注入
setupLocator();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedProvider<Container>(
container: container,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
),
);
}
}
4. 使用依赖注入和状态管理
在你的页面或组件中,你可以使用ScopedContainer
来获取依赖:
import 'package:flutter/material.dart';
import 'package:katana_scoped/katana_scoped.dart';
import 'app_container.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final container = ScopedContainer.of<Container>(context);
final myService = container.get<MyService>();
return Scaffold(
appBar: AppBar(
title: Text('Katana Scoped Demo'),
),
body: Center(
child: Text(myService.getMessage()),
),
);
}
}
5. 复杂状态管理示例
如果你需要管理更复杂的状态,比如用户信息,你可以创建一个状态管理类并注册到容器中:
// user_state.dart
import 'package:katana_scoped/katana_scoped.dart';
class UserState {
String? username;
void setUsername(String username) {
this.username = username;
}
}
然后在app_container.dart
中注册这个状态管理:
// app_container.dart
import 'package:katana_scoped/katana_scoped.dart';
import 'user_state.dart';
final container = Container();
void setupLocator() {
container.registerSingleton<MyService>(() => MyService());
container.registerSingleton<UserState>(() => UserState());
}
在你的页面中使用这个状态管理:
// my_home_page.dart
import 'package:flutter/material.dart';
import 'package:katana_scoped/katana_scoped.dart';
import 'app_container.dart';
import 'user_state.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final container = ScopedContainer.of<Container>(context);
final userState = container.get<UserState>();
final myService = container.get<MyService>();
return Scaffold(
appBar: AppBar(
title: Text('Katana Scoped Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(myService.getMessage()),
SizedBox(height: 20),
Text('Username: ${userState.username ?? 'Not Set'}'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
userState.setUsername('John Doe');
setState(() {}); // 注意:由于MyHomePage是无状态的,这里不能直接调用setState。在真实场景中,你可能需要将状态提升到有状态组件。
},
child: Text('Set Username'),
),
],
),
),
);
}
}
注意:由于MyHomePage
是无状态组件,它不能直接调用setState
来刷新UI。在实际应用中,你可能需要将状态管理逻辑提升到有状态组件,或者使用Provider
、GetX
等更强大的状态管理库来处理UI刷新。这里仅作为演示katana_scoped
的基本用法。
希望这个示例能帮助你理解如何在Flutter中使用katana_scoped
进行依赖注入和状态管理。