Flutter多端应用开发

2023-09-22Flutter框架

一、背景及目标

1、背景

在使用 Flutter 开发跨平台应用时,我们发现现有应用的逻辑代码和视图代码没有充分解耦。这在开发多端(如iOS、Android、Mac、Windows、Web)场景下,不利于复用已编写的逻辑,从而影响开发效率。我们可以利用 Mixin 的能力解决这个问题

2、目标

在不影响现有功能的基础上,重构应用的业务代码。通过复用重构后的逻辑代码,快速完成 APP 端的功能迁移到桌面端,提高代码的一致性、扩展性,并适配多端场景。

二、解决方案

1、移动端应用(APP)

对现有代码进行改造:

(1)将APP页面中的 State 抽离,封装成 StateMixin(StateMixin:继承于 State 的 mixin)。

(2)保留APP页面的UI代码,将封装好的StateMixin进行混入,以还原业务实现。

2、其他平台

通过复用封装的 StateMixin,采用 View+StateMixin 的方式实现业务,从而实现逻辑层的跨平台复用:

(1)将多端共用的属性和方法提取并封装成基类(BaseState),统一处理可复用的业务逻辑。

(2)将各端差异化的属性和方法提取并封装成子类(如AppState、DesktopState、WebState),以个性化处理各端差异化的业务。

3、StateMixin

mixin BaseState<T extends BaseView> on State<T> {}
mixin AppState<T extends AppView> on BaseState<T> {}
mixin DesktopState<T extends DesktopView> on BaseState<T> {}
mixin WebState<T extends WebView> on BaseState<T> {}

4、Widget

class BaseView extends StatefulWidget {}
class AppView extends BaseView {}
class _AppViewState extends State<AppView> with BaseState, AppState {}
class DesktopView extends BaseView {}
class _DesktopViewState extends State<DesktopView> with BaseState, DesktopState {}
class WebView extends WebView {}
class _WebViewState extends State<WebView> with BaseState, WebState {}

三、优势

(1)最小化对现有代码的修改。

(2)充分解耦各平台代码。

(3)通过子类覆盖父类方法,灵活应对各种业务场景。

对现有 APP 代码的改动较小,只需将 State 中的属性和方法迁移至 mixin 文件,保留 widget 视图代码。然后将 mixin 文件重新混入视图代码中,即可完成 APP 代码的重构。其他平台可直接复用 mixin。对于 APP 中原有的方法名、属性名和逻辑,基本无需调整。

注意事项
(1)抽离至mixin中的属性或方法不能设为私有(正确示例:name;错误示例:_name)
(2)混入mixin时,基类必须放在子类前面(示例:State<AppView> with BaseState, AppState)
(3)可以通过基础视图类BaseView处理页面间传参。

四、具体实施

1、view 实现

(1)通过适配层动态渲染 APP 和 桌面端 UI视图。

(2)通过 mixin 实现逻辑复用。

// index.dart
Widget build(BuildContext context) {
 // 通过视图适配层,收敛多端视图的适配
 return AdapterLayout(
  mobile: AppGroupShareView(todoLabel: widget.todoLabel,),
  desktop: DesktopGroupShareView(todoLabel: widget.todoLabel),
 );
}
// base_group_share_view.dart
abstract class BaseGroupShareView extends StatefulWidget {
 const BaseGroupShareView({Key? key, required this.todoLabel})
   : super(key: key);
 final TodoLabel todoLabel;
}

// app_group_share_view.dart
class AppGroupShareView extends BaseGroupShareView {
 AppGroupShareView({Key? key, required todoLabel})
   : super(todoLabel: todoLabel);
 @override
 _AppGroupShareViewState createState() => _AppGroupShareViewState();
}
class _AppGroupShareViewState extends State<AppGroupShareView>
  with BaseGroupShareMethod, AppGroupShareMethod {}


// desktop_group_share_view.dart
class DesktopGroupShareView extends BaseGroupShareView {
 const DesktopGroupShareView({Key? key, required todoLabel})
   : super(todoLabel: todoLabel);
 @override
 _DesktopGroupShareViewState createState() => _DesktopGroupShareViewState();
}
class _DesktopGroupShareViewState extends State<DesktopGroupShareView>
  with BaseGroupShareMethod, DesktopGroupShareMethod {}

2、mixin 实现

// base_group_share_method.dart
mixin BaseGroupShareMethod<T extends BaseGroupShareView> on State<T> {
 get isCreate {
  // 业务逻辑
  reture 1
 }
 void initState() {
  super.initState();
  // 业务逻辑
  // ...
 }
 // 可直接使用
 void backGroupShare() {
   resetLabel();
 }
 // 需子类实现
 void jumpToContactView() {}
 // 需子类实现
 void refreshUI() {}
}


// app_group_share_method.dart
mixin AppGroupShareMethod<T extends AppGroupShareView>
  on BaseGroupShareMethod<T> {
 void backGroupShare() {
  // 调用父类方法
  super.backGroupShare();
  Get.back();
 }
 // 重新方法,各端差异实现
 void jumpToContactView() {
  Get.to(() => Contact());
 }
 // 刷新UI
 refreshUI() {
  TDStore().todoLabelsStore.fetchServerData().then((value) {
   // ...
  });
 }
}

// desktop_group_share.method
mixin DesktopGroupShareMethod<T extends DesktopGroupShareView>
  on BaseGroupShareMethod<T> {
 // 重新方法,各端差异实现
 void jumpToContactView() {
  print('跳转桌面端');
 }
}

五、总结

本文中,我们提供了一种 Flutter 实现多端应用开发中逻辑层的复用与解耦的方案。通过对现有代码的改造和封装,我们能够在最小化对现有代码的修改的同时,充分解耦各平台代码,并灵活应对各种业务场景。

版权声明:来自网友下山,版权归原作者所有

原文链接:https://www.webppp.com/view/flutter_duo_duan_ying_yong_kai_fa.html