Flutter 控件
Flutter Control 是一个用于维护应用程序和状态管理的复杂库。
该库将多种功能整合到一个框架中。这种方法有助于将分离的逻辑整齐地捆绑到复杂的解决方案中。
import 'package:flutter_control/core.dart';
- 应用状态管理 - 管理应用状态、本地化、主题和其他全局应用更改。
- 控件状态管理 - UI / 逻辑分离。控制状态和 UI 更新。
- 依赖注入 - 工厂、单例、延迟初始化和服务定位器。
- 导航和路由 - 路由、过渡以及向其他页面和模型传递参数。
- 本地化 - 基于 Json 的本地化,具有基本格式。
- 事件系统 - 全局事件/数据流,轻松通知应用事件。
Flutter Control 核心
Control主静态类。初始化ControlFactory并提供对大多数核心 [Control] 对象(如BaseLocalization、RouteStore、ControlBroadcast等)的简便访问。ControlFactory初始化并可以存储控件、模型和其他对象。它作为服务定位器和存储。
工厂有自己的存储。此存储中的对象可以通过自定义键或类型访问。最佳实践是使用类型作为键。
工厂是此库中唯一一个单例。
Flutter Control 的核心对象默认存储在工厂的存储中(Control.initControl),可以通过它们的Type或通过 Provider 访问。

Control.initControl(
localization: LocalizationConfig(
defaultLocale: 'en',
locales: LocalizationAsset.map(locales: ['en_US', 'es_ES']),
),
entries: {
CounterListControl: CounterListControl(),
},
initializers: {
CounterModel: (_) => CounterModel(),
CounterDetailControl: (args) => CounterDetailControl(model: Parse.getArg<CounterModel>(args)),
},
routes: [
ControlRoute.build<DetailPage>(builder: (_) => DetailPage()),
],
initAsync: () async {
loadPreAppConfig();
},
);
ControlRoot包装基本应用流程并初始化 [Control]。它只是一个开始使用 Flutter Control 的快捷方式。通过ControlScope,可以维护此根 Widget 的State并控制整个应用状态(本地化、主题等)。
此外,还提供应用状态管理 - 主屏幕、本地化和主题更改。
ControlRoot(
localization: LocalizationConfig(locales: [...]),
theme: ThemeConfig<MyThemne>(
builder: (context) => MyTheme(context),
themes: {...},
),
entries: {...},
initializers: {...},
routes: [...],
states: [
AppState.init.build(builder: (_) => LoadingPage()),
AppState.main.build(
builder: (_) => DashboardPage(),
transition: TransitionToDashboard(),
),
],
app: (setup, home) => MaterialApp(
key: setup.key,
title: setup.title('app_name', 'Example App'),
theme: setup.theme,
home: home,
locale: setup.locale,
supportedLocales: setup.supportedLocales,
localizationsDelegates: [
...
],
),
);
-
ControlWidget是基类抽象(StatefulWidget),用于维护应用的较大 UI 部分(页面或复杂 Widget)。Widget 使用默认的ControlState创建,以正确地将 Widget 的生命周期反映到模型中。因此,无需创建自定义 [State]。
Widget 将初始化所有包含的模型并向它们传递参数。
ControlWidget是不可变的,因此所有逻辑部分(甚至 UI 逻辑和动画)都必须从外部控制。这有助于真正分离所有代码与纯 UI(也有助于重用这些代码)。 -
SingleControlWidget专注于单个 ControlModel。但仍然可以处理多个控件。 -
ControllableWidget- 订阅一个或多个Observable- [ObservableComponent]、[ActionControl]、[FieldControl]、[Stream]、[Future]、[Notifier]
每当 [ControlObservable] 的状态发生更改时,此 Widget 就会重建。这些 Widget 附带一些
mixin类RouteControl用于抽象导航,轻松地将参数传递给路由并初始化其他页面。TickerControl和SingleTickerControl用于创建带有Ticker的 [State] 并提供对vsync的访问。LocalizationProvider、ThemeProvider、OnLayout、ControlsComponent等..
-
ControlModel是用于维护业务逻辑部分的基类。
BaseControl是 [ControlModel] 的扩展版本,具有更多功能。主要用于页面或复杂 Widget,也用于分离健壮的逻辑部分。
BaseModel是 [ControlModel] 的扩展但轻量级的版本。主要用于控制列表中的项等较小 Widget,或用于分离/重用逻辑部分。
这些控件附带一些mixin类来扩展基本功能ObservableComponent用于控制状态并通知 Widget 更改。TickerComponent将Ticker传递给模型,并支持在 Widget 外部控制动画。

-
ControlObservable和ControlSubscription是核心底层可观察系统,也是其他具体健壮实现的抽象基类 - 主要为 [ActionControl] 和 [FieldControl]。
在 Widget 端使用ControlBuilder和ControlBuilderGroup。这些通用构建器 Widget 可以处理所有可能的 Notifier 类型。 -
ActionControl是此库中使用的一种 Observable。它非常轻量级,用于通知 Widget 并提供有关值更改的事件。
有两种变体 -单例(只有一个监听器),广播(多个监听器)。
在 Widget 端使用ControlBuilder来动态构建 Widget。也可以使用ControlBuilderGroup来组合多个 Observable 的值。
在 [ActionControl] 销毁时,所有ControlSubscription都会关闭。
final counter = ActionControl.broadcast<int>(0);
ActionBuilder<int>(
control: counter,
builder: (context, value) => Text(value.toString()),
);
FieldControl是围绕Stream和StreamController的更健壮的 Observable 解决方案。主要用于通知 Widget 并提供有关值更改的事件。
可以监听Stream、Future或订阅另一个 [FieldControl],并能够过滤和转换值。
[FieldControl] 附带预构建的原始变体,如StringControl、DoubleControl等,可以用于验证、正则表达式或值限制。还有ListControl用于处理 Iterables。
在 Widget 端使用FieldBuilder来动态构建 Widget。还可以使用ControlBuilderGroup来与多个 Observable 一起使用。也可以使用标准的StreamBuilder。
FieldSink或FieldSinkConverter提供 [FieldControl] 的Sink。
在 [FieldControl] 销毁时,所有FieldSubscription都会关闭。
final counter = FieldControl<int>(0);
FieldBuilder<int>(
control: counter,
builder: (context, value) => Text(value.toString()),
);
下面的结构显示了数据和事件如何在 UI 和控件之间流动。ControlWidget 可以使用多个 ControlModel,其中包含多个模型、Stream 和 Observable。

本地化
BaseLocalization基于 Json 的本地化,支持简单字符串、复数和动态结构。
通过LocalizationProvidermixin 轻松访问。本地化对象存储在 [ControlFactory] 中,因此无需 Context 即可访问,并且可以通过Control.localization()在模型、实体等中使用。
本地化默认在Control中初始化和加载。
默认情况下,ControlWidget通过 mixin 使用此本地化。
Control.initControl(
localization: LocalizationConfig(
defaultLocale: 'en',
locales: LocalizationAsset.map(locales: ['en_US', 'es_ES']),
),
);
ControlRoot(
localization: LocalizationConfig(
locales: {
'en': 'assets/localization/en.json',
'es': 'assets/localization/es.json',
},
),
);
全局事件系统
ControlBroadcast贯穿整个应用的事件流。默认广播器是ControlFactory的一部分并存储在那里。
每个订阅都绑定到其key和Type,因此通知仅发送给预期数据的监听器。
通过BroadcastProvider,可以订阅任何流,并将数据或事件从应用的某个部分发送到另一个部分,甚至发送到 Widget 及其状态。
还可以创建自定义广播器来将事件与全局/默认流分离。

BroadcastProvider.subscribe<int>('on_count_changed', (value) => updateCount(value));
BraodcastProvider.broadcast('on_count_changed', 10);
导航和路由
ControlRoute为RouteHandler指定具有Transition和 [WidgetBuilder] 设置的Route。Handler 然后处理导航并将参数传递给 Widget 和模型。
使用RouteControlmixin 来启用 [ControlWidget] 的此导航,并使用RouteControlProvidermixin 来启用 [ControlModel] 的此导航。
路由可以存储在RouteStore中,并且可以通过ControlRoute.of静态访问路由构建器。
Control.initControl(
routes: [
ControlRoute.build<DetailPage>(builder: (_) => DetailPage()),
ControlRoute.build(key: 'detail_super', builder: (_) => DetailPage()).path('super').viaTransition(_transitionBuilder),
],
);
class ListPage extends ControlWidget with RouteControl {
Widget build(BuildContext context){
...
routeOf<DetailPage>().openRoute();
routeOf<DetailPage>().viaTransition(_transitionBuilder).openRoute();
routeOf(key: 'detail_super').openRoute();
};
}
其他类
-
ControlTheme和ThemeProvider包装 [ThemeData]、[MediaQuery] 和资源路径助手。 -
InputField是 [TextField] 的包装器,通过InputControl提供更多功能和控制。 -
DisposeHandler- 任何类的 mixin,有助于对象处理。 -
PrefsProvider- 任何类的 mixin,有助于存储用户偏好设置 - 基于 shared_preferences。 -
Parse帮助解析 json 原始类型和 Iterables。还有助于查找列表和地图中的对象。 -
FutureBlock可重新触发的延迟。 -
DelayBlock延迟以包装代码块,以防止“超级快速”完成和 UI 抖动。 -
WidgetInitializer帮助使用 init 数据初始化 Widget。 -
UnitId基于时间、索引或随机数的唯一 ID 生成器。 -
等等..