Flutter模板插件template_package的功能使用
Flutter模板插件template_package的功能使用
template_package
一个用于Flutter应用的模板包。
该包将为您提供一组工具,以加快并保持您的应用开发的清洁度。
- 状态管理
- 使用类似于但比常见的Flutter bloc更灵活的方式管理Flutter状态
- 用UseCase接口实现并组织应用逻辑
- LoggerDefault用于记录所有必需的日志
- Flutter toast等实用程序已经包含在内
- BaseBlocDataState、BaseBlocPrimaryState状态和BaseBlocEvent用于组织您的小部件和bloc之间的数据流
功能模块
功能 | 模块 |
---|---|
状态管理 | BaseWidget 和 TemplateBloc |
导航 | BaseBlocPrimaryState 和 sinkState |
日志 | LoggerDefault |
业务规则模块 | ABR 和 EBR |
依赖注入 | BaseDependencyModule |
开始使用
状态管理
将小部件转换为接受bloc状态的小部件
让我们从将您的StatefulWidget转换为接受来自bloc(TemplateBloc)的状态的小部件开始。
扩展您的StatefulWidget以继承BaseWidget,并且您的状态类也应继承BaseState。同时添加额外的泛型类型<PageName, BaseBloc>
。
// 定义一个使用BaseWidget的小部件
class MyWidget extends BaseWidget {
MyWidget(BaseBloc Function() getBloc) : super(getBloc);
@override
_MyWidgetState createState() => _MyWidgetState();
}
// 定义一个使用BaseState的小部件状态类
class _MyWidgetState extends BaseState<MyWidget, BaseBloc> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: myWidgetListener(),
);
}
// 注意这里的StreamBuilder监听来自MyCustomDataState Stream的数据
Widget myWidgetListener() {
return StreamBuilder(
stream: bloc.getStreamOfType<MyCustomDataState>(),
builder: (BuildContext context, AsyncSnapshot<MyCustomDataState> snapshot) {
if (snapshot.data == null)
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('no data received'),
],
),
);
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(snapshot.data?.myCustomData ?? ''),
SizedBox(height: 10),
sendDataToBlocButton(),
],
),
);
},
);
}
// 定义一个按钮,用于向bloc发送数据
ElevatedButton sendDataToBlocButton() {
return ElevatedButton(
onPressed: () {
bloc.event.add(MyButtonTapCustomEvent('myAnalyticEvent', dataFromUi: "data from UI"));
},
child: Text('Send Data To Bloc'),
);
}
}
创建bloc
import 'dart:async';
import 'package:example/features/initial/initial_event.dart';
import 'package:example/features/initial/initial_state.dart';
import 'package:template_package/template_package.dart';
class MyBloc extends BaseBloc {
final StreamController myDataStateController = StreamController<MyCustomDataState>();
MyBloc() {
// 注册自定义控制器,否则会导致Flutter错误
registerStreams([
myDataStateController.stream,
// someOtherController.stream
]);
}
@override
void onUiDataChange(BaseBlocEvent event) {
// 任何由基础小部件发送的事件最终都会到这里
// 确保通过确切类型过滤它们(事件需要扩展BaseBlocEvent)
if (event is MyCustomEvent) {
callMethodThatWillDoSomething(event.dataFromUi);
} else if (event is MyButtonTapCustomEvent) {
doSomethingOnButtonTap(event.dataFromUi);
}
}
void doSomethingOnButtonTap(String dataFromUi) {
print(dataFromUi);
myDataStateController.add(MyCustomDataState(myCustomData: "$dataFromUi with my custom data"));
}
void callMethodThatWillDoSomething(String dataFromUi) {
// todo 做一些事情
}
@override
void dispose() {
// 关闭你的控制器
myDataStateController.close();
super.dispose();
}
}
创建一个文件来保存你的数据状态并创建你的数据状态
class MyCustomDataState extends BaseBlocDataState {
final String myCustomData;
MyCustomDataState({required this.myCustomData});
}
创建一个文件来保存你的事件并创建你的BaseBloc事件
class MyCustomEvent extends BaseBlocEvent {
final String myCustomDataFromUi;
MyCustomEvent(String? analyticEventName, this.myCustomDataFromUi) : super(analyticEventName);
}
这里是如何这些元素之间通信的一个概述:
让我们看看如何组合这些依赖项
/// 如果你没有自定义分析,可以使用默认的AnalyticsProxy()
/// 构造函数中的参数非常自定义,没有任何限制,就像getIt一样
final page = MyWidget(() => MyBloc());
导航
导航类
class NavigateToMyPage extends BaseBlocPrimaryState {
final Function(dynamic result)? onPop;
final String variable;
NavigateToMyPage({this.onPop, required this.variable, bool rootNavigator = true}) : super();
@override
call(context) {
final page = MyWidget(() => MyBloc());
Navigator.of(context).push(MaterialPageRoute(builder: (context) => page)).then((value) {
return onPop?.call(value);
});
}
}
如何从一个widget导航
void methodInMyWidget(BuildContext context) {
NavigateToMyPage(params).call(context);
}
如何从一个bloc导航
void methodInMyBloc() {
sinkState?.add(NavigateToMyPage(params));
}
依赖注入
创建一个或多个子模块(创建一些模块的地方)
class BlocSubModule extends ISubModule {
// late ServiceSubModule serviceSubModule;
@override
init(List<ISubModule> subModules) {
// 你可以从这个方法访问到你应用的所有子模块
// serviceSubModule = subModules.singleWhere((element) => element is ServiceSubModule) as ServiceSubModule;
}
SecondBloc secondBloc(String someData) => SecondBloc(someData, serviceSubModule.userService());
}
创建初始化所有子模块的模块
class DependencyModule extends BaseDependencyModule {
@override
List<ISubModule> createSubmodules() {
return [
BlocSubModule(),
// ServiceSubModule()
// CoreSubModule()
];
}
}
创建一个提供者,这将允许访问你需要的子模块
99%的情况下,你应该只需要访问blocSubModule
class DProvider extends InheritedWidget {
final List<ISubModule> _subModuleList;
@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
/// 必须在小部件树的顶部初始化(应该是App的父级)
const DProvider(this._subModuleList, {required Widget child, Key? key}) : super(child: child, key: key);
static DProvider? of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<DProvider>();
///Bloc SubModule
BlocSubModule get blocSubModule => _subModuleList.whereType<BlocSubModule>().first;
///Bloc SubModule
EbrSubModule get ebrSubModule => _subModuleList.whereType<EbrSubModule>().first;
}
初始化依赖模块
初始化你的依赖模块,并将所有子模块传递给依赖提供者。确保你的应用被DProvider包裹。
void main() {
final dependencyModule = DependencyModule();
final app = DProvider(dependencyModule.getReadySubModules(), child: const MyApp());
runApp(app);
}
获取你的依赖
final exampleDependency = DProvider.of(context)!.myCustomSubModule.myCustomDependency();
SecondPage(() => DProvider.of(context)!.blocSubModule.secondBloc(someData));
UseCases
class SomeUseCase extends UseCase<InitialRepository> {
SomeUseCase(InitialRepository repository) : super(repository);
Future<void> getSomeData(RequestObserver<dynamic, SomeModel?> requestObserver) async {
await repository.getSomeData(RequestObserver<dynamic, SomeModel?>(
onListen: (SomeModel? data) {
// 一些额外的逻辑
requestBehaviour.onListen?.call(data);
},
onError: requestBehaviour.onError));
}
Future<void> setSomeData(RequestObserver<SomeModel?, dynamic> requestObserver) async {
await repository.setSomeData(RequestObserver<SomeModel?, dynamic>(
requestData: requestBehaviour.requestData,
onListen: (_) {
requestBehaviour.onListen?.call(_);
},
onError: requestBehaviour.onError));
}
}
更多关于Flutter模板插件template_package的功能使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复