Flutter 控件

Flutter Control 是一个用于维护应用程序和状态管理的复杂库。
该库将多种功能整合到一个框架中。这种方法有助于将分离的逻辑整齐地捆绑到复杂的解决方案中。

import 'package:flutter_control/core.dart';
  • 应用状态管理 - 管理应用状态、本地化、主题和其他全局应用更改。
  • 控件状态管理 - UI / 逻辑分离。控制状态和 UI 更新。
  • 依赖注入 - 工厂、单例、延迟初始化和服务定位器。
  • 导航和路由 - 路由、过渡以及向其他页面和模型传递参数。
  • 本地化 - 基于 Json 的本地化,具有基本格式。
  • 事件系统 - 全局事件/数据流,轻松通知应用事件。

Flutter Control 核心

  • Control 主静态类。初始化 ControlFactory 并提供对大多数核心 [Control] 对象(如 BaseLocalizationRouteStoreControlBroadcast 等)的简便访问。
  • ControlFactory 初始化并可以存储控件、模型和其他对象。它作为服务定位器和存储。
    工厂有自己的存储。此存储中的对象可以通过自定义类型访问。最佳实践是使用类型作为键。
    工厂是此库中唯一一个单例。
    Flutter Control 的核心对象默认存储在工厂的存储中(Control.initControl),可以通过它们的 Type 或通过 Provider 访问。

Structure

    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 用于抽象导航,轻松地将参数传递给路由并初始化其他页面。
    • TickerControlSingleTickerControl 用于创建带有 Ticker 的 [State] 并提供对 vsync 的访问。
    • LocalizationProviderThemeProviderOnLayoutControlsComponent 等..
  • ControlModel 是用于维护业务逻辑部分的基类。
    BaseControl 是 [ControlModel] 的扩展版本,具有更多功能。主要用于页面或复杂 Widget,也用于分离健壮的逻辑部分。
    BaseModel 是 [ControlModel] 的扩展但轻量级的版本。主要用于控制列表中的项等较小 Widget,或用于分离/重用逻辑部分。
    这些控件附带一些 mixin 类来扩展基本功能

    • ObservableComponent 用于控制状态并通知 Widget 更改。
    • TickerComponentTicker 传递给模型,并支持在 Widget 外部控制动画。

Structure

  • ControlObservableControlSubscription 是核心底层可观察系统,也是其他具体健壮实现的抽象基类 - 主要为 [ActionControl] 和 [FieldControl]。
    在 Widget 端使用 ControlBuilderControlBuilderGroup。这些通用构建器 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 是围绕 StreamStreamController 的更健壮的 Observable 解决方案。主要用于通知 Widget 并提供有关值更改的事件。
    可以监听 StreamFuture 或订阅另一个 [FieldControl],并能够过滤和转换值。
    [FieldControl] 附带预构建的原始变体,如 StringControlDoubleControl 等,可以用于验证、正则表达式或值限制。还有 ListControl 用于处理 Iterables。
    在 Widget 端使用 FieldBuilder 来动态构建 Widget。还可以使用 ControlBuilderGroup 来与多个 Observable 一起使用。也可以使用标准的 StreamBuilder
    FieldSinkFieldSinkConverter 提供 [FieldControl] 的Sink
    在 [FieldControl] 销毁时,所有 FieldSubscription 都会关闭。
    final counter = FieldControl<int>(0);

    FieldBuilder<int>(
      control: counter,
      builder: (context, value) => Text(value.toString()),
    );

请在 Git 仓库中查看 计数器示例待办事项列表示例


下面的结构显示了数据和事件如何在 UI 和控件之间流动。ControlWidget 可以使用多个 ControlModel,其中包含多个模型、Stream 和 Observable。
Structure


本地化

  • BaseLocalization 基于 Json 的本地化,支持简单字符串、复数和动态结构。
    通过 LocalizationProvider mixin 轻松访问。本地化对象存储在 [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',
        },
      ),
    );

请在 Git 仓库中查看 本地化示例本地化委托示例

全局事件系统

  • ControlBroadcast 贯穿整个应用的事件流。默认广播器是 ControlFactory 的一部分并存储在那里。
    每个订阅都绑定到其 keyType,因此通知仅发送给预期数据的监听器。
    通过 BroadcastProvider,可以订阅任何流,并将数据或事件从应用的某个部分发送到另一个部分,甚至发送到 Widget 及其状态。
    还可以创建自定义广播器来将事件与全局/默认流分离。

Structure

  BroadcastProvider.subscribe<int>('on_count_changed', (value) => updateCount(value));
  BraodcastProvider.broadcast('on_count_changed', 10);

导航和路由

  • ControlRouteRouteHandler 指定具有 Transition 和 [WidgetBuilder] 设置的 Route。Handler 然后处理导航并将参数传递给 Widget 和模型。
    使用 RouteControl mixin 来启用 [ControlWidget] 的此导航,并使用 RouteControlProvider mixin 来启用 [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();
      };
    }

请在 Git 仓库中查看 导航示例导航堆栈示例


其他类

  • ControlThemeThemeProvider 包装 [ThemeData]、[MediaQuery] 和资源路径助手。

  • InputField 是 [TextField] 的包装器,通过 InputControl 提供更多功能和控制。

  • DisposeHandler - 任何类的 mixin,有助于对象处理。

  • PrefsProvider - 任何类的 mixin,有助于存储用户偏好设置 - 基于 shared_preferences

  • Parse 帮助解析 json 原始类型和 Iterables。还有助于查找列表和地图中的对象。

  • FutureBlock 可重新触发的延迟。

  • DelayBlock 延迟以包装代码块,以防止“超级快速”完成和 UI 抖动。

  • WidgetInitializer 帮助使用 init 数据初始化 Widget。

  • UnitId 基于时间、索引或随机数的唯一 ID 生成器。

  • 等等..

GitHub

https://github.com/RomanBase/flutter_control