Flutter ConstraintLayout 1.6 发布,带来了创新的开放式语法

发布于 2022-7-7 17:14
浏览
0收藏

 

说明

开放式语法是我发明的新词,它是啥意思呢?我们看看代码就明白了。

class OpenGrammarExample extends StatelessWidget {
  const OpenGrammarExample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ConstraintLayout().open(() {
        if (DateTime
            .now()
            .millisecond % 2 == 0) {
          Container(
            color: Colors.red,
          ).applyConstraint(
            size: 200,
            centerTo: parent,
          );
        } else {
          Container(
            color: Colors.yellow,
          ).applyConstraint(
            size: 200,
            centerTo: parent,
          );
        }

        for (int i = 0; i < 5; i++) {
          Row().open(() {
            for (int j = 0; j < 10; j++) {
              Text("$i x $j").enter();
              const SizedBox(
                width: 20,
              ).enter();
            }
          }).applyConstraint(
            height: 100,
            left: parent.left.margin(100),
            top: i == 0 ? parent.top : sId(-1).bottom,
          );
        }

        int i = 0;
        while (i < 100) {
          Text("$i").applyConstraint(
            left: parent.left,
            top: i == 0 ? parent.top : sId(-1).bottom,
          );
          i++;
        }
      }),
    );
  }
}

 

是不是感受到了?

你无需指定 children 参数,而是直接调用 open 扩展函数,在 Lambda 中声明子元素,这些子元素会自动加入到 ConstraintLayout 的 children 列表。这样的好处是显而易见的。你可以在 Lamda 表达式中使用任何 Dart 的语法来声明子元素,而不仅仅局限于 Dart 数组提供的简单的表达式语法。

这个 open 扩展函数对 Row、Column、Stack 都有效,你以前写的代码,可以更优雅的实现了。

以前:

Stack(
  children: [
    if (loading) CircularProgressIndicator(),
    if (!loading && data == null) LoadErrorWidget(),
    if (!loading && data != null) ListView()
  ],
);

 

现在:

Stack().open(() {
  if (loading) {
    CircularProgressIndicator().enter();
    // Some other code
  } else if (data == null) {
    LoadErrorWidget().enter();
    // Some other code
  } else {
    ListView().enter();
    // Some other code
  }
});

 

ConstraintLayout 的子元素无需调用 enter 将自身加入到父元素,applyConstraint 会自动将其加入。

我认为这真正意义上实现了声明式 UI,以前你给父元素指定 child、children 都是命令式的将子元素加入到父元素。

此外,weiV 也带来了多项全新特性。

weiV 特性一览

1. 可扩展
1. 轻松适配第三方控件以实现声明式 API
2. 内部的实现可替换,比如 Text 默认使用 TextView 渲染,你可以替换成 AppCompatTextView
2. 基于 WebView 提供了 JsContext,配合 WeiVParser 可实现简易的动态化,后面会继续增强
3. 友好的、完整的支持 Java
4. 提供了 XmlViewWidget 让你无需写扩展即可内嵌所有现有 View 并实现声明式 API
5. 提供了 StatefulWidget 以实现子树状态的单独管理,有了它你不再需要 Fragment
6. 提供了 WeiVView、WeiVJavaView 来把 weiV 嵌入到任何地方
7. 提供了 ConstWidget 达到了和 Flutter const Widget 同样的效果
Kotlin:

class WeiVCounterKotlinActivity : WeiVActivity() {
    override fun build(buildCount: Int) = WeiV {
        // 使用 Const 包裹的子树不会得到更新,Lambda 只会执行一次
        Const(buildCount = buildCount) {
            Text(text = "Widgets wrapped by Const will not be updated, count = $count")
        }
    }
}

 

Java:

class WeiVCounterJavaActivity extends WeiVJavaActivity {
    public WeiV build(int buildCount) {
        // 使用 Const 包裹的子树不会得到更新,Lambda 只会执行一次
        Const(buildCount, () -> {
            Text().wText("Widgets wrapped by Const will not be updated, count = " + count);
        });
    }
}

 

8.提供了全局 Widget 创建和更新的 Hook,可轻松实现换肤、夜间模式

9.提供了 UI 模块化方案

近期计划:

1. 完善声明式架构的核心逻辑,以支持 Widget、Element、View 三棵树高效更新
2. 移植 Flutter ConstraintLayout 以实现上述性能目标,并带来前所未有的开发效率和体验,Compose 提供的 ConstraintLayout 还没摆脱命令式思维,用起来实在是低效
3. 重写 RecyclerView、ViewPager2 等常用核心控件以实现声明式 API
4. 对所有系统内置常用组件进行包装以实现声明式 API,部分可能会重写
5. 以极其简单的方式支持动画,属性动画在声明式体系下已不合适
6. 开发布局预览,这个可能有点麻烦
7. 移植 Flutter PVState,提供在声明式 UI 下更轻量好用的状态管理方案
8. 为 Android 实现带状态的热重载。通过开发一个 Android Studio 插件,当你更改了代码以后,插件根据最新代码生成 Widget 树的 JSON 并通过 ADB 发送到 App,App 将 JSON 还原成真实的 Widget 树并重新渲染 UI。整个过程应用的状态得以保留。这将进一步提升 Android 开发的效率
预计所有的代码写完,代码量在 3 万行左右。

终极目标:Java 下的唯一声明式 UI 开发框架,Kotlin 下比 Compose 更好的声明式 UI 开发框架。

有人可能会说 Compose 支持跨平台,我想跨平台你应该首选 Flutter 而不是 Compose。

在任何时候都应该优先考虑使用 Flutter 来开发 UI 部分。即便没有跨端的需求,在性能不成问题的时,它带给你的效率是成倍的。未来也许 80% 的 UI 将采用 Flutter 构建。如果你因为嵌套地狱放弃了 Flutter,那么现在是时候重新捡起来了,因为我的 Flutter ConstraintLayout 已经根治了嵌套地狱。

点击查看原文可下载 weiV Counter apk,它的大小只有 41 KB,构建 release 混淆包只用了 4 秒。

 

文章转自公众号:FlutterFirst

已于2022-7-7 17:14:03修改
收藏
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐