[Flutter翻译]在安卓系统上,Flutter应用程序缺少的是原生的外观和感觉

1,641 阅读5分钟

原文地址:medium.com/@volskaya/w…

原文作者:medium.com/@volskaya

发布时间:2021年7月26日-5分钟阅读

当我和其他人谈论Flutter框架时,我总是争论说,它实际上并不像原生的,如果开发者关心这样的东西,他们仍然需要投入额外的工作。

这里有一些你应该使用的调整,让你的Flutter应用看起来更像原生的。


现代设备上的输入事件重取样

在iOS平台方面,针对新的、高采样率的屏幕上不规则的输入传递,实施了一个旧的修复。虽然这完全忽略了Android,因为最初这个问题被认为只发生在iPhone上。

image.png

启用输入重采样的Dart代码

现在,就像2年后,我们在飞镖方面有了这个修正。它不是默认开启的,但可以通过调用GestureBinding.instance!.resamplingEnabled = true;来启用。虽然这个方法会带来巨大的输入延迟,而且可能看起来不对劲。

因为我的应用程序甚至不能滚动最基本的内容,而且没有可行的修复方法,我不得不挖掘Flutter自己的飞镖代码,并在DragGestureRecognizer中添加代码,每帧只允许一个 "真实 "的输入事件,其余的被视为 "徘徊",在当前和下一帧之间被平滑掉。

这种 "真实 "和 "徘徊 "的输入事件方法使我的滚动和翻转与原生的输入延迟相同。我将自己写一篇关于其他人如何实现这个的文章,直到上游被修复。


高刷新率显示模式的偏好

人们现在应该用这个来设置最高刷新率和分辨率的显示模式,或者在他们的MainActivity中实现同样的逻辑,如下面的代码所示。

image.png

MainActivity内的Kotlin代码

之所以需要这样做,是因为新的安卓手机有花哨的120hz屏幕,当屏幕上有视频、游戏或某种媒体时,会有一个优化,将帧率降到60hz。我不确定系统是如何决定何时降低帧数的,但我猜想当屏幕上有SurfaceView时就会发生这种情况。

Flutter在SurfaceView上绘制自己的图形,所以会跳过这个优化。我还没有遇到过任何Flutter应用实现这个功能。


避免固定范围和动态大小的项目滚动视图之间的翻转动画的差异

在弹跳动画中存在着错误的差异。这是因为Flutter的可滚动代码中的某些东西一直在重启弹跳动画。

我发现它是由 ScrollPosition.applyContentDimensions 中的 _pendingDimensions = true; 的单一赋值引起的。

这个赋值会导致每次有新的动态尺寸的孩子被滚动到视图中时调用applyNewDimensions();,然后导致弹道飞行动画被重新启动。 通过添加尺寸检查,我能够修复弹跳的怪异现象,例如 if (!_haveDimensions) applyNewDimensions();

image.png

ScrollPosition的applyContentDimensions的Dart代码


让应用程序按照现代安卓的指导方针,从边缘画到边缘

image.png

Flutter最近合并了一些工作,这些工作在稳定版上还不能使用。这最终允许Android应用程序跨越整个屏幕,并像iOS一样在导航栏下绘制。

希望这种模式将成为新的默认模式,因为它在安卓上应该是这样的。现在,由于调用是在dart端进行的,在初始化过程中,导航条仍然会嵌入应用程序,这可能会使闪屏跳动。

image.png

启用Edge to Edge模式的Dart代码

你可以将SystemChrome.setEnabledSystemUIMode添加到你的应用程序的构建函数中,当你的Flutter版本有此变化时。


将闪屏从原生视图无缝过渡到Flutter视图

默认情况下,当您打开 Flutter 应用程序时,会出现一个白屏--原生视图,然后在 Flutter 视图中淡出。

image.png

MainActivity内的Kotlin代码

这是一个巧妙的覆盖,允许你在MainActivity中覆盖闪屏。

它用一个静态动画取代了默认的闪屏。现在,当没有更多的时间浪费在本机视图的动画上时,你可以在Flutter那边做一些动画。

1.gif

Napy应用程序的闪屏

你可以看到在这个GIF中,我让原生屏幕和Flutter中的飞溅屏幕绘制了相同的图标,背景是相同的紫色。在应用程序完成初始化后,我在条形图中制作了动画,并将其导向主屏幕,创造了一个无缝的、原生的飞溅屏幕。


从默认的滑动页面过渡到缩放页面

在定义你的主题时,你也应该选择一个更先进的页面过渡。

默认情况下,Flutter使用旧的 "向上滑动 "页面过渡,模仿Android 9的过渡,但自Android 10以来,原生活动的动画是缩放页面动画。

image.png

设置Flutter应用程序主题的Dart代码示例

如果你使用这个动画,你也应该考虑把Flutter的MaterialRouteTransitionMixin.transitionDuration从300ms重写到450ms,这样动画就和原生的相匹配了。


你还可以做其他微小的改变,以获得更好的感觉和性能。

  • 使用AlwaysScrollableScrollPhysics()作为默认的滚动物理学。
  • 使用这个中的UnboundedCustomScrollView。
  • 将const double kTouchSlop = 8;改为8。默认情况下是16。

www.deepl.com 翻译