1

我有两个应用程序“屏幕”,AB。两者都SystemChrome.setEnabledSystemUIOverlays在构建方法中设置。

一套按照

  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
    return WillPopScope(
    ....

B设置为

  Widget build(BuildContext context) {
    if (MediaQuery.of(context).orientation == Orientation.landscape) {
      SystemChrome.setEnabledSystemUIOverlays([]);
    }
    else {
      SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
    }
    return WillPopScope(
    .....

纵向从A导航到B效果很好。但是,如果我在B中输入景观,颤动会删除覆盖,然后立即重新实现它们,即我看到覆盖消失并很快重新出现。如果我从A完全删除覆盖线,B工作正常。它就像B被重建,然后是A但在后台。那是一回事吗?

我像这样导航

Navigator.push(context, MaterialPageRoute(builder: (mContext) => DataForm(file: _file)))

三天来,我一直在跟踪这个错误。作为参考,在我的所有代码中仅在此处设置了叠加层。该问题仅发生在 Android 上。

我很欣赏第一反应是'它在你的代码中,我们需要看到它来解决它'。我尝试在“最小代码”中重现该问题以发布示例,但我无法让错误再次发生,而且我的代码非常广泛,我不知道如何全部展示。

根据标题,我改为询问哪些场景可能导致屏幕A覆盖设置在每次构建时影响屏幕B。

提前致谢!

4

1 回答 1

0

在追踪我的错误 5 天后回答我自己的问题,希望将来它可能会有所帮助。我怀疑那些有经验的人会想‘当然是’,所以这可能更适合像我这样的新人。

SystemUIOverlay就像一个全局变量,持久存在于应用程序中,并自动跨屏幕实现。新的屏幕/代码可以随时更改此覆盖设置,并知道是否将全局和追溯地应用于所有屏幕。在我的情况下SystemUIOverlay,设置为build因此屏幕A中强制重建的任何操作将因此强制更新并将全局覆盖值应用于B

即使屏幕A没有显示,它也可以在触发后继续在后台重建,即使屏幕B已打开。因此,在B打开时触发A重建的任何事情都意味着B将全局采用A的覆盖设置。这就是我看到的结果。

几个例子:

如此处所引用,只要 MediaQueryData 发生变化(例如,如果用户旋转他们的设备) ,MediaQuery.of就会使您的小部件自动重建。因此,例如,如果您在 Screen A的构建中的任何位置包含“MediaQuery.of” ,则即使不在焦点上也可能会发生构建。然后, A的这种重建会在全局范围内强制执行它的覆盖值,该值由B在打开时拾取。

在我的情况下,重建B将覆盖设置为[]并影响insets. MediaQueryA中接受了这一点,重建并将覆盖重置为.values并将它们强制到B上。她走了一圈。

在A中调用 setState 的周期性计时器将执行相同的操作。我相信还有更多的例子。

因此,当 A 失去焦点时,请注意并避免A中的任何重建潜力。

于 2020-08-18T06:16:33.550 回答