同步操作将从 LEARN/MXFlutter 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
MXFlutter v0.2.5 发布配套 mxjsbuilder v0.0.2 编译器,支持编译 Flutter 工程为 mxflutter 可运行的 JS 代码。
体验包下载地址 MXFlutter_v0-2-5.apk
运行 MXFlutter
如果本机是 Flutter Channel stable,请更新到最新 tag:v1.17.0
如果遇到其他问题,可在QQ群(747535761)中讨论。
MXFlutter 是一套基于 JavaScript 的 Flutter 框架,可以用极其类似 Dart 的开发方式,通过编写 JavaScript 代码,来开发 Flutter 应用,或者使用 mxjsbuilder 编译器,把现有Flutter 工程编译为JS,运行在 mxflutter 之上。代码位置 MXFlutter Github ,可以安装 Android的包来体验 MXFlutter_v0-1-2.apk ,更多细节在 基于JavaScript的Flutter框架详细介绍。
把 Flutter 的渲染逻辑中的三棵树(即:WidgetTree、Element、RenderObject )中的第一棵(即:WidgetTree),放到 JavaScript 中生成。用 JavaScript 完整实现了 Flutter 控件层封装,可以使用 JavaScript,用极其类似 Dart 的开发方式,开发Flutter应用,利用JavaScript版的轻量级Flutter Runtime,生成UI描述,传递给Dart层的UI引擎,UI引擎把UI描述生产真正的 Flutter 控件。所以,它在iOS上是完全动态化的。
关于MXFlutter动态化框架渲染、优化等更多详细细节介绍,请看文档:基于JavaScript的Flutter框架详细介绍。
MXFlutter,就是用JavaScript,以Flutter的写法开发Flutter。具体的项目结构分为三层,请看下图:
mxflutter 是一个标准的 Dart package,可以按照 Dart 引入 package 的方式接入,步骤非常简单。在开始接入之前,运行体验 mxfltuter 的两个例子,对接入会有帮助,一个是示例丰富但比较复杂的例子,在 https://github.com/mxflutter/mxflutter.git 主库根目录,一个是最简化接入示例,在主库 mxflutter/example/ 目录下 ,推荐第一次接入按照第二个例子来。
dependencies:
mxflutter: ^0.2.5
因为mxflutter在快速迭代,推荐 fork 在 github 的主库 https://github.com/mxflutter/mxflutter.git 来接入,方便自己修改和定期从主库的更新。
dependencies:
mxflutter:
git:
url: https://github.com/mxflutter/mxflutter.git
path: mxflutter/
第一步拷贝JS代码文件:mxflutter 主库提供了JS代码模版,拷贝主库 mxflutter/example/mxflutter_js_src (https://github.com/mxflutter/mxflutter/tree/master/mxflutter/example/mxflutter_js_src) 文件夹到你的工程目录,和pubspec.yaml文件同级。
第二步在 pubspec.yaml 文件中引入 mxflutter_js_src 代码资源文件夹
flutter:
assets:
- mxflutter_js_src/
特别注意:第一步拷贝的文件夹和第二步导入的资源是配套的,因为 pubspec.yaml 导入资源时,不会自动导入子文件夹, 如果你是拷贝的主库根目录 https://github.com/mxflutter/mxflutter/tree/master/mxflutter_js_src 文件夹,要配套按照主库 pubspec.yaml 的资源配置来引入,学习接入建议使用 mxflutter/example/mxflutter_js_src 的示例
完成后目录结构应该是这样的
my_flutter/
├── lib/
│ └── main.dart
└── pubspec.yaml
└── mxflutter_js_src/
│ └── main.js
│ └── home_page.js
│ └── js_dev_demo.js
│ └── mxjsbuilder_demo.js
在 main.dart 文件中,调用 runJSApp 启动JSApp,runJSApp 函数如果不传任何参数,默认会运行 mxflutter_js_src/mian.js 文件
//mxflutter
import 'package:mxflutter/mxflutter.dart';
void main() {
//-------1. MXFlutter 启动---------
MXJSFlutter.getInstance().runJSApp();
runApp(MyApp());
}
在合适时机,比如用户点击界面时,打开JS页面。
onTap: () {
//-------2. MXFlutter push 一个使用MXFlutter框架编写的页面
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MXJSPageWidget(
jsWidgetName: "MXJSWidgetHomePage")));
}
上面代码 MXJSPageWidget 的参数 jsWidgetName: "MXJSWidgetHomePage",在mxflutter_js_src/main.js MyApp::createJSWidgetWithName 函数中使用,用来标示打开哪个JS页面。
先看看使用效果,以下截图是在MXFlutter框架下用JS开发,大家可以把上面的源码下载下来,里面有完整的JS代码示例:
单页面演示
下图是APP示例截图:
下面是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,
}),
}),
});
}
项目演示
源码中还有更丰满的示例,高仿知乎页面JSFlutter版,可以点此进入查看代码:
下图是对应的UI,已经接近在线上版直接使用了:
本项目里面高仿知乎页面示例借鉴了 zhihu-flutter 的示例代码,在此,鸣谢作者 HackSoul。
MXFlutter遵循MIT开源许可证协议。
MXFlutter还需要很多工作去完善功能,修改BUG,建设配套设施,如果大家有兴趣,欢迎加入一起开发。
如果你有好的意见或建议,也欢迎给我们提 Issues
或 Pull Requests
。
特别感谢以下开发者的贡献
成员
项目成员luca浪哥,nice,yockie帅哥贡献了动画,控件,示例APP等核心实现, chaodong老师负责了DartVM方案,wenn和不咸同学负责了Android平台的实现,IP老师提供了单元测试,健身大神yofer老师负责了代码维护,工具建设。
项目由来
18年10月份,团队开始引入 Flutter,Flutter 功能强大,开发快捷,但不能像ReactNative一样使用JavaScript语言开发,为了扩展Flutter的开发者阵营,所以启动了这个技术探索项目。
现状
要实现JS开发Flutter是一个很大的工程,团队成员平时工作也非常繁忙,只能业余时间投入,所以人力情况非常紧张,如果大家有兴趣,期待小伙伴们一起加入,共同建设 MXFlutter ,各自为战,不如一起做一个完善的。
由于项目代码量大,时间紧张,MXFlutter还有很多遗留的问题,作为一个技术探索,非常辛苦但非常有趣,期待各位大牛指导,期待小伙伴们提出问题一起讨论解决。
要了解全部,一定要拉下源码,运行起来看看,有问题可以留言一讨论,MXFlutter会持续更新。
MXFlutter Team
是一个技术氛围浓厚,有美女有帅哥有趣有爱的团队,欢迎终端,后台,前端同学投递简历哦:mxflutter@qq.com
对MXFlutter有兴趣的小伙伴,可以加群交流 QQ群:747535761
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。