老孟导读:此文翻译自:https://medium.com/@suragch/my-first-disappointment-with-flutter-5f6967ba78bf

我喜欢Flutter。我喜欢开发一次并让代码在Android和iOS上运行。我喜欢节省多少时间。我喜欢现在成为一名Web开发人员,而无需做任何额外的工作。我喜欢hot reload。我喜欢通过将小部件组合到布局中来快速构建UI。我喜欢制作ListView简单得多。我喜欢状态管理。 (好吧,只是在开玩笑。但是我可以应付。)我喜欢Dart。我喜欢Future和async / await比Android AsyncTasks甚至iOS Dispatch Queue容易得多。

但是,在花了最后两周的时间研究Flutter如何呈现文本后,我对使用的工具感到失望。

我们被告知:

Flutter的分层体系结构使您可以控制屏幕上的每个像素。

这显然不适用于用于绘制文本的像素。

Flutter中的低级文字功能

Flutter使用名为LibTxt的库结合使用Skia,Hafbuzz,Minikin和ICU来呈现文本。开发人员在使用Text小部件或TextSpan甚至是TextPainter时间接使用它。在最低级别上,我们可以使用dart:iu,它是使用ParagraphBuilder构建的Paragraph类。这些类基本上只是底层LibTxt引擎的包装器。几乎所有工作都由此引擎完成,而在dart:ui中几乎没有暴露。

Paragraph类为我们提供了以下控制:

  • Size:我可以获取整个渲染段落的宽度和高度,它可以是单行或多行。
  • 距基线的距离(仅对于第一行)
  • 文本是否溢出了maxLines变量。
  • 文本框的大小和相对位置。这是一个例子:

  • 最接近某个像素位置的文本字符索引。在上面的示例中,像素(1、1)对应于字符串中的索引0,即“My text line.”的字母“ M”。
  • 字符串中某些字符偏移的单词边界。

随后的更新也为我们提供了LineMetrics,它为每行提供了许多详细信息:

class LineMetrics {
final bool hardBreak;
final double ascent;
final double descent;
final double unscaledAscent;
final double height;
final double width;
final double left;
final double baseline;
final int lineNumber;
}

但是,我们没有得到:

  • 一种在文本框中获取实际文本的方法。
  • 一种控制文本布局方式的方法。
  • 一种在路径上绘制文本的方法。
  • 一种无需绘制整个段落即可测量和绘制短文本的方法。
  • 一种从文本字符串获取换行位置的方法

与Android和iOS的比较

在Android中,尽管大多数人会使用TextView,但是您可以通过使用StaticLayout,Canvas和Paint类获得低级控件来执行上面列出的所有操作。以下是可用的众多选项中的几个:

我在iOS上没有那么低级的文字绘制经验(因为我认为我只会学习在Flutter中做所有事情),但是Core Text具有丰富的工具集。

Flutter 指南中如此说:

以多个平台为目标的SDK是很常见的……提供可在所有目标平台上运行的API。不幸的是,这通常意味着一个平台或另一个平台独有的功能不可用。

对于Flutter,我们希望通过明确地成为每个平台的最佳开发方式来避免这种情况。我们在跨平台上使用的能力仅次于我们在每个平台上使用的能力。 (添加了重点)

当前,对于需要在应用程序中进行低级文本渲染的我们当中,Flutter并不是最好的开发平台。

用例

您可能会说Flutter已经提供了Text和RichText小部件。是的,他们非常好。他们将满足99.9%的开发人员的需求。但是,存在使用较低级别的文本呈现工具的用例。

蒙文

我的用例是布局并渲染传统的蒙古文字,该文字垂直书写,并从左到右换行。英语是侧身书写,但CJK和表情符号字符应保持其正常方向。

有一些使用小部件组合的“解决方案”,但是当您添加文本样式的需要时(例如通过在文本的右侧绘制一条垂直线来“下划线”),一种更可靠的解决方案是处理所有文本手工测量,布置和绘画。我已经开始在这里工作了

中文,日文和韩文

中文,日文和韩文也可以按各种垂直方向进行布局。像蒙古语一样,有一种解决方法,可以解决一次性情况,但对于常用用法,渲染包会更有帮助。阅读此内容以更详细地描述需求。

Flutter仅支持支持从右到左和从左到右的布局。不支持(也不支持)垂直布局。我不会对此表示怀疑。有很多工作。但是我希望他们会给我们更多工具来自己做。

艺术文字

进行文字绘画的应用程序也将从对文字绘画工具的低级别访问中受益。

用文本填充非矩形形状

为了使文本适合非矩形的内容,您必须进行大量测量。换行在哪里是另一个难题。

文字围绕排除路径流动

这在iOS中可用,但在Flutter中不可用。而且没有简单的方法可以自己实现。

结论

我并不是想说服任何人不要使用Flutter。我还是很喜欢我再也不想回到为不同平台构建同一应用程序的多次了。

在撰写本文时,我希望有人会说:“不,你错了。如果您这样做,那么您将可以使用低级文本呈现工具。”不过,我对此并没有寄予太大希望,因为Flutter的主要开发人员之一对此表示

如果您想要“真实的”垂直文本,并带有强调标记,ruby和内联水平的bidi文本以及所有内容,那么我能提供的最好的办法是,您可以尝试使用我们提供的较差的原语编写一个程序包来支持此操作,但是可能不会是令人满意的体验。

我真正希望的是Flutter小组将为我们提供与UI布局级别一样的文本自由。添加一个dart:ui类以暴露更多LibTxt库并不是特别困难。的确,维护起来会更多,开发人员可能偶尔会用它来编写效率低下的代码,但我认为自由值得付出代价。使Flutter成为使用任何语言开发任何平台的最佳方式。

2020年2月更新

当我最初发布这篇文章时,Flutter团队迅速做出了回应(请参阅下面的评论)。许多工作正在完成(如GitHub问题所记录,谢谢Gary Qian),并且希望可能会有一些重大的改进。但是,尽管遭到了强烈支持,但该GitHub问题最终因其工作量过多而被关闭。

最近得知,正在完成用Skia SkParagraph模块替换LibTxt的工作。这听起来很令人兴奋,但是我还不知道细节。您可以在此处跟踪进度。由于这是一项重大更改,因此现在是让Flutter团队了解您的需求与自定义文本呈现相关的好时机。请参阅以下部分。

你可以做什么

即使以下问题当前已关闭(尽管尚未解决),如果您还需要执行自定义文本呈现,请继续对其进行投票并在其上留下评论。

地址:https://github.com/flutter/flutter/issues/35994

为了将问题分解为更小的部分,我添加了以下特定功能要求。如果您还需要它们,请投票和/或评论。

我尚未提交任何具体的错误报告,但与许多小型Paragraph对象的测量和绘画效率有关。原因是我自己没有发现任何性能问题。如果您遇到过此类问题,请创建一个详细的GitHub问题,并@suragch me。我会在这里链接到它。

交流

老孟Flutter博客地址(330个控件用法):http://laomengit.com

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

我对Flutter的第一次失望的更多相关文章

  1. 关于Flutter初始化流程,我必须告诉你的是...

    1. 引言 最近在做性能优化的时候发现,在混合栈开发中,第一次启动Flutter页面的耗时总会是第二次启动Flutter页面耗时的两倍左右,这样给人感觉很不好.分析发现第一次启动Flutter页面会做 ...

  2. flutter本地环境的安装以及编辑器的配置

    由于本文图片比较多,所有都缩小了不少,点击图片就可以放大看到原始图片 使用镜像 cmd打开终端,贴上以下代码,以加入到环境变量中,如果添加失败,可以手动添加 export PUB_HOSTED_URL ...

  3. 闲鱼Flutter&FaaS云端一体化架构

    讲师介绍 国有,闲鱼架构团队负责人.在7月13号落幕的2019年Archsummit峰会上就近一年来闲鱼在Flutter&FaaS一体化项目上的探索和实践进行了分享. 传统Native+Web ...

  4. Flutter的环境配置以及一些常见问题

    flutter & AndroidStudio flutter的下载与配置 flutter是Google推出的基于Dart语言开发的跨平台开源UI框架,能够支持安卓与iOS. flutter框 ...

  5. Flutter 第一次运行就出现白屏的问题

    --enable-software-rendering 解决办法: 顶部菜单找到 run-->Edit Configurations 中加这么一句:

  6. NOIP2015游记——一次开心又失望的旅行

    啊,一年一度的NOIP终于是结束了 以前的大神都有写自己的感受 然而我居然给忘了!!!! 吓得我赶紧来写一份游记 Day.-INF--出发前一个星期 机智的我选择了停课 就是为了OIER这伟大而又光荣 ...

  7. 团队作业4——第一次项目冲刺(Alpha版本)第五天

    天气阴转晴 一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 1.界面 功能界面已经大致完成 实现判断学生答题正误的界面 2.出题方面 实现错题库的构造 四.困难与问题 1.项 ...

  8. Android程序员的Flutter学习笔记

    作为忠实与较资深的Android汪, 最近抽出了一些时间研究了一下Google的亲儿子Flutter, 尚属皮毛, 只能算是个简单的记录吧. Google自2017年第一次提出Flutter, 到20 ...

  9. Android Studio集成Flutter

    首先Flutter中文网教程地址:https://flutterchina.club/get-started/install/ 1.新建环境变量 变量名:PUB_HOSTED_URL 变量值:http ...

随机推荐

  1. Elasticsearch入门指南

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 这篇文章主要是记录一下最近在学的 ...

  2. apicloud版人人商城app打包教程

    一.APP环境搭建和配置编译1.登录APICLOUD后台新建应用 步骤一 .注册账号注册apicloud 账号并登录APICLOUD控制台 注册apicloud 账号:https://www.apic ...

  3. 修改jar包配置文件的正确操作,jar包解压出来的文件夹重新打成jar,不依靠开发工具!!!!

    修改jar包配置文件的正确操作,有的时候通过一些解压工具可以对内部的文件进行修改,但是有时候会无效.这就很烦了 一.背景:       有一个springboot项目,事先我已经用编译好打成jar包以 ...

  4. java流程控制语句if

    一 if语句 if语句是指如果满足某种条件,就进行某种处理. 格式: if (条件语句){ 执行语句; …… } 流程图: 例如: public class IfDemo01 { public sta ...

  5. java 模拟斗地主发牌洗牌

    一 模拟斗地主洗牌发牌 1.案例需求 按照斗地主的规则,完成洗牌发牌的动作. 具体规则: 1. 组装54张扑克牌 2. 将54张牌顺序打乱 3. 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张 ...

  6. 从一次外卖到对oauth2.0的思考

    别问oauth1.0哪去了,问就是不好讲. 1. 外卖并不好吃   今天下班得早,想吃顿好的,于是就点了一份外卖,过了一会儿,外卖到了,但是在小区大门被堵住了,我亲自远程开门后才能进来,又过了一会,被 ...

  7. 关于初次使用Thymeleaf遇到的问题 2020-08-11

    关于初次使用Thymeleaf遇到的问题 环境: IDEA :2020.1 Maven:3.5.6 SpringBoot: 2.3.2 原做法: 按照视频教程,导入依赖,并修改报的版本为3.0.9,适 ...

  8. Salesforce学习笔记之lwc

    1.在Flow中使用Lightning Web Component(lwc)时,发现一个问题.给这个组件设置了一个输入参数,其值取自前一个Screen.第一次运行时,参数的值正确,但是如果这时退回前一 ...

  9. onlyoffice在线编辑

    一.安装ONLYOFFICE Document Server 二.集成onlyoffice的二次开发 三.故障排除: 四.缺陷 五.总结 ONLYOFFICE Document Server提供文档协 ...

  10. linux驱动之模块化编程

    今天刚开始学习linux驱动的编写.在网上开了许多网友的博客,感觉比较好的摘抄下来,以便以后忘记可以随时查看.下面是摘抄文章的地址,非常感谢他们. http://blog.chinaunix.net/ ...