本文为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
复制代码
Ceci est la deuxième partie de la série "Flutter Engineering Framework Selection". Comme je l'ai déjà dit, cette série vous indique simplement comment choisir rapidement un module fonctionnel qui vous convient lorsque vous créez un projet Flutter, ou construisez un échafaudage de projet Flutter. , ou il s'agit d'une série de guides, elle convient donc mieux aux étudiants novices.
Cet article présente principalement l'interface utilisateur, mais il semble un peu compliqué d'introduire simplement l'interface utilisateur, c'est-à-dire d'ajouter quelques connaissances pour absorber l'eau .
En tant que développeurs front-end, la plupart de nos responsabilités consistent à développer l'interface utilisateur, mais ne serait-il pas formidable que quelqu'un nous aide à créer l'interface utilisateur à l'avance ? En fait, plusieurs fois, l'interface utilisateur peut en effet être modélisée, et le champ frontal a toujours été comme ça, par exemple Ant Design
, Element-UI
etc. Existe-t-il un tel support sur Flutter ?
La réponse est définitivement oui, mais avant de les présenter, parlons d'un problème de Flutter UI : nesting .
Pour ne pas être trop larmoyant, parlons technologie en préface, et préconisons des projets en seconde partie.
Préface - Imbrication de l'interface utilisateur
En ce qui concerne Flutter, certaines personnes doivent dire imbrication. Oui, Flutter Widget
lui-même rend l'interface utilisateur par imbrication directe , vous pouvez donc vous plaindre du code suivant, bien que ce code n'ait aucun sens, mais ici, nous devons penser à deux choses première question :
- Flutter a-t-il peur que l'
Widget
imbrication affecte les performances ? - Existe-t-il un moyen pour Flutter de résoudre l'imbrication ?
Le premier point est que Flutter n'a généralement pas peur que l'imbrication affecte les performances.Pour des raisons "bien connues", Flutter n'est Widget
pas un vrai contrôle, je préfère dire que c'est Widget
un fichier de configuration, et les vrais objets de dessin et de mise en page sont derrière .et toute RenderObejct
autre logique connexe .
嵌套层级看起来很多的原因,是因为
Widget
颗粒度太细。
当然这个还要看你嵌套的 Widget
做了什么?或者说是嵌套的 Widget
的 RenderObject
做了什么,例如:
Padding
的RenderPadding
就是在 layout 时多了一个Size
和childParentData.offset
计算ColoredBox
的_RenderColoredBox
就是多一句drawRect
Align
的RenderPositionedBox
就是多计算一个childParentData.offset
所以这些 Widget
的颗粒度很细,但是也很轻,我们直接用的时候可能会一层一层嵌套,看起来不美观,但是实际渲染时对性能影响不大。
当然,并不是所有的
Widget
都很轻不怕嵌套,例如Clip
、Transform
和Opacity
等,如果涉及到pushLayer
等操作时,在需要做图层合成的时候,那确实对性能影响还是比较大的。
那第二个问题,如何解决嵌套?这时候你就需要 “配置模版” ,通过封装来优化代码结构。
“配置模版”是什么意思?举个例子 : Container
应该用过吧? Container
其实就是官方给大家准备的 “模版” ,它本身只是一个 StatelessWidget
,也就是一个没有 RenderObject
的 Widget
,它靠的就是把各种功能的 Widget
组合起来使用,如下图就是使用 Container
的对比情况。
所以在使用 Flutter 构建 UI 时,就可以谈及到两个点:
Widget
是配置文件,它一般很轻,不怕嵌套,真正绘制渲染的是它背后的RenderObject
- 通过各种 UI 配置模版来解决嵌套,特别是抽象出适合自己业务逻辑的 UI 模版
举个例子,如下方的第三方开源布局包 dashboard ,在这种复杂的 UI 布局上难道就靠直接一级一级嵌套 Column
和 Row
来解决?答案肯定不是!
dashboard 的是通过 Stack
+ Positioned
组成模版,在手势移动时计算,通过 AnimatedBuilder
实现动画偏移,自动计算控件位置。
其实也可以直接用
AnimatedPositioned
,具体可见 《Flutter 小技巧之有趣的动画技巧》
所以可以看到, Flutter 里你其实可以不那么嵌套,具体还是看你的封装方式,除了这样,还有就是直接在 RenderObject
上进行自定义布局,比如下方这两个例子:
cloud | custom_multi_render |
---|---|
你说上面的布局用 Stack
+ Positioned
的模式能不能做?肯定是可以,但是在 RenderObject
层实现不是更优雅吗?把脏活累活写在 RenderObject
, 通过 Widget
提供配置接口,这样就不会一上来就向用户露 “底裤” 不是么。
所以,把眼界打开,不要什么都盯着
Widget
嵌套,往RenderObject
层面探索,你会发现 Flutter 其实不像表面那么浮躁,再不济来尝试下CustomMultiChildLayout
,它也可以帮助你解决一些复杂布局下的嵌套问题。
当然,还有一些项目另辟蹊径,比如 niku ,这个项目通过 typedef
和抽象拓展,利用语法对官方控件进行二次封装,实现创建了一个 “非正道” 的 UI 配置效果,具体如下图所示,喜不喜欢就看个人爱好了,但是它确实一定程度解决了嵌套可视化的问题。
作者是个二次元,但是看地址他应该是泰国哥们
当然,我们这一期的关键是提高 UI 生产力,单说源码实现就没劲了,所以重点让我们看后半部分。
UI 套件
在前端领域,使用统一的 UI 套件可以加快开发的节奏,减少开发和设计之间的摩擦,而且风格统一。一般情况下,在企业内部都是在不知不觉中沉淀下来各种组件,最后形成组件池,从而落地成 UI 套件。
比如贝壳的 bruno ,我愿意称它为 Flutter 界的 Element-UI
,目前已经支持到 Flutter 3 ,作为少有国内大厂维护的 Flutter UI 项目,甚至它还提供了 sketch 设计指引 和 设计物料下载 。
bruno | getwidget | fsuper |
---|---|---|
当然,除了 bruno 之后,像 getwidget 、 fsuper 也提供了日常开发中常用的 UI 套件,虽然风格风格上可能并没有 bruno 统一,但是还是可以在一定程度提高开发的生产力。
事实上对于个人开发者来说,这种套件可以解决很多设计上的问题。
另外聊到 Flutter UI 套件就要一定要介绍国内的 fluttercandies 组织,fluttercandies 是由大佬们共同维护的一系列 Flutter 开源项目,记住,是大佬们,并且一直在持续更新:
- extended_image
- extended_nested_scroll_view
- extended_text
- extended_text_field
- extended_list
- extended_sliver
- extended_tabs
- wechat_assets_picker
- waterfall_flow
举个例子,如果 flutter framework 短期不能解决的问题,那就大佬就会 cv 一份控件自己维护,这就是 fluttercandies 的节奏和优势。
PC
既然介绍 Flutter UI ,就不得不介绍 PC 相关的风格的 UI ,因为 Flutter 不只是 Android 和 iOS ,它还支持 Web 和 PC, 所以类似 PC 的 UI 风格也值得推荐,比如 ant_design_flutter 就是一个很有意思的项目。
fluent_ui | macos_ui | ant_design_flutter |
---|---|---|
Responsive
那有的人可能就说,我想要一套代码适配多平台的屏幕尺寸行不行?答案肯定是可以的,下面这几个 package 就提供了不同屏幕尺寸下一套代码的动态适配方案,我个人可能会比较喜欢 ResponsiveFramework 。
ResponsiveFramework | responsive_sizer | flutter_adaptive_ui |
---|---|---|
Appbar
这类 Appbar 的实现其实是我被问过最多的,其实它的核心实现都是 Sliver ,严格意义上我觉得并不需要第三方库,自己用 Sliver 就可以实现,但是本着能不动手就不动手原则,也推荐几个库吧:
draggable_home | extended_sliver | scroll_app_bar |
---|---|---|
gsy_flutter_demo 里也提供了几种实现思路,其实并不复杂。
Drawer
可能有人会觉得,不会吧不会吧, Drawer 也需要第三方库?
还真有,因为有时候可能需要不一样的动画效果,另外这里的 sidebarx
,也和官方提供的 NavigationRail
有异曲同工之妙,能在 UI 上适配多平台的操作习惯。
sidebarx | flutter_advanced_drawer | curved_drawer |
---|---|---|
Tarbar
既然都说到 Drawer
,那 Tabbar
也提供几个花里胡哨的动画效果,主要是切换时的动画效果,另外 tab_container
可能算是比较有意思的库,用的 Path
来编绘背景动画效果。
flutter-cupertino-tabbar | tab_indicator_styler | tab_container |
---|---|---|
BottomBar
说到 Tabbar
相对应的还有 BottomBar 相关,这里也提供几个库,主要是动画效果很有趣,我个人还是挺喜欢这种曲线的动画效果。
curved_navigation_bar | salomon_bottom_bar | bubble_bottom_bar |
---|---|---|
指引
启动指引这个需求,正常情况下一个 PageView
就可以满足产品经理的场景,但是有时候可能会需要你来“亿”点点动画效果来增加 KPI,所示拿着也许就对你有用了,当然你也可以把它当作 PageView
动画来使用。
concentric_transition | nice_intro | intro_views_flutter |
---|---|---|
角标
这个应该无需多言了,基本上 App 都会需要用到,这两个库基本覆盖了 90% 的场景
flutter_badges | corner_decoration |
---|---|
动画按键
这个可能一般情况下大家都不需要这么花里胡哨的效果,但是万一呢?Material 风格上这种交互还是挺多的,不过国内对 Material 确实不是很感冒。
flutter_animated_button | progress_state_button |
---|---|
头像
没想到吧?头像为什么还需要库?
其实就是下面的这个场景,相信这个场景可能大家都不会陌生,有社交需求的时候,经常会存在这样的 UI ,掘金沸点不也有类似 UI 么?
avatar_stack | overflow_view | |
---|---|---|
swipe 卡片
这个需求可能一般人不会需要,推荐它是因为我还记得几年的时候,收了 1000 给人做了这样的一个外包,就是做一个这样的控件。
swipe_deck | swipeable_card_stack | appinio_swiper |
---|---|---|
bottom sheet
这其实更多是一个 Route 相关的动画效果,感觉好像国内也不常用到,但是之前确实有好几次咨询有没有类似的实现。
we_slide | sliding_up_panel |
---|---|
时间轴 UI
这是我在群里被问过好多次的一个需求场景,我也不知道为什么那么多应用会需要用到这样的 UI ?不过这类需求自己从头实现确实会比较费事。
timeline_tile | timelines |
---|---|
好了,关于 Flutter UI 相关的内容推荐就到这里,本篇主要还是提供给大家如何理解 Flutter 的 UI 布局,并且尽可能去解决嵌套,同时提供一些有意思的第三方 package ,进一步提高大家开发 UI 的生产力。
最后,如果你还有什么关于 Flutter 工程或者框架的疑问,欢迎留言评论,也许新的素材又有了~