乐趣区

MXFlutter基于JS的Flutter框架用JS也能写出Flutter应用

项目名称:MXFlutter
项目作者:MXFlutter Team
开源许可协议:MIT
项目地址:https://gitee.com/huoxd/MXFlu…

项目简介

MXFlutter 是一套基于 JavaScript 的 Flutter 框架,可以用极其类似 Dart 的开发方式,通过编写 JavaScript 代码,来开发 Flutter 应用,或者使用 mxjsbuilder 编译器,把现有 Flutter 工程编译为 JS,运行在 mxflutter 之上。

项目特性

  • 支持 Dart Flutter 语法
  • 支持定义 Flutter 中同名 Widget 类
  • 支持定义相同的 Build 方式,SetState 刷新及事件响应方法
  • 支持 js 模块化开发
  • 支持模拟器页面热更新

核心思想

把 Flutter 的渲染逻辑中的三棵树(即:WidgetTree、Element、RenderObject)中的第一棵(即:WidgetTree),放到 JavaScript 中生成。用 JavaScript 完整实现了 Flutter 控件层封装,可以使用 JavaScript,用极其类似 Dart 的开发方式,开发 Flutter 应用,利用 JavaScript 版的轻量级 Flutter Runtime,生成 UI 描述,传递给 Dart 层的 UI 引擎,UI 引擎把 UI 描述生产真正的 Flutter 控件。所以,它在 iOS 上是完全动态化的。

项目结构

MXFlutter,就是用 JavaScript,以 Flutter 的写法开发 Flutter。具体的项目结构分为三层,请看下图:

1.VM 层:

  • MXFlutter Runtime
  • 定义和 Flutter Widget 同名镜像类
  • 响应式 UI 框架

2.Flutter 层:

  • Script 脚本管理模块
  • DSL2Widget UIEngine,事件支持
  • Dart 业务 API 支持
  • 内存管理,对象生命周期管理

3.Native 层:

  • VM 虚拟机
  • 线程管理
  • Native 业务 API 支持
  • 项目效果 UI 展示
  • 单页面演示


下面是 UI 截图对应的 JS 代码,没错,你没有眼花,这个是真的 JavaScript 代码,可以在 MXFlutter 的运行时库上渲染出 Flutter 的 UI,(是不是很像 Flutter 里面的组件代码)!

class JSPestoPage extends MXJSWidget {constructor() {super("JSPestoPage");
    this.recipes = recipeList;

  }

  build(context) {
    let statusBarHeight = 24;
    let mq = MediaQuery.of(context);
    if (mq) {statusBarHeight = mq.padding.top}

    let w = new Scaffold({
      appBar: new AppBar({title: new Text("Pesto Demo")
      }),
      floatingActionButton: new FloatingActionButton({child: new Icon(new IconData(0xe3c9)),
        onPressed: function () {},
      }),
      body: new CustomScrollView({
        semanticChildCount: this.recipes.length,
        slivers: [//this.buildAppBar(context, statusBarHeight),
          this.buildBody(context, statusBarHeight),
        ],
      }),
      //body:this.buildItems()[0]
    });

    return w;
  }

  buildAppBar(context, statusBarHeight) {
    return SliverAppBar({
      pinned: true,
      expandedHeight: _kAppBarHeight,
      actions: [
        IconButton({icon: new Icon(new IconData(1)),
          tooltip: 'Search',
          onPressed: function () {},
        }),
      ],
      flexibleSpace: LayoutBuilder({builder: function (context, constraints) {
          size = constraints.biggest;
          appBarHeight = size.height - statusBarHeight;
          t = (appBarHeight - kToolbarHeight) / (_kAppBarHeight - kToolbarHeight);
          extraPadding = new Tween({begin: 10.0, end: 24.0}).transform(t);
          logoHeight = appBarHeight - 1.5 * extraPadding;
          return Padding({
            padding: EdgeInsets.only({
              top: statusBarHeight + 0.5 * extraPadding,
              bottom: extraPadding,
            }),
            child: Center({child: new Icon(new IconData(1))
            }),
          });
        },
      }),
    });
  }

  buildBody(context, statusBarHeight) {let mediaPadding = EdgeInsets.all(0);
    let mq = MediaQuery.of(context);
    if (mq) {mediaPadding = MediaQuery.of(context).padding;
    }
    let padding = EdgeInsets.only({
      top: 8.0,
      left: 8.0 + mediaPadding.left,
      right: 8.0 + mediaPadding.right,
      bottom: 8.0
    });

    return new SliverPadding({
      padding: padding,
      sliver: new SliverGrid({
        gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent({
          maxCrossAxisExtent: _kRecipePageMaxWidth,
          crossAxisSpacing: 8.0,
          mainAxisSpacing: 8.0,
        }),
        delegate: new SliverChildBuilderDelegate(function (context, index) {let recipe = this.recipes[index];
            let w = new RecipeCard({
              recipe: recipe,
              onTap: function () { showRecipePage(context, recipe); },
            });

            return w;
          },
          {childCount: this.recipes.length,}),
      }),
    });
  }

如果你想要了解它更详细的使用和接入方法,那么就点击后面的链接前往项目主页看看吧:https://gitee.com/huoxd/MXFlu…

退出移动版