首页 文章

InheritedWidget更新导致问题

提问于
浏览
1

我在应用程序顶部使用继承的小部件,以便在设置新位置时更新我的应用程序 . 这样可以在我的应用中的每个可能位置刷新我的位置坐标 .

但是我也有一个文本字段 . 几秒钟后,当我点击文本字段时,键盘将被继承的窗口小部件的更新隐藏 . 有没有办法防止颤动隐藏键盘或重新初始化状态,以便继承的小部件的更新与我的搜索字段一起工作? It should be also possible that when i enter some text that this trigger the inherited widget for a new update but the search bar and keyboard should stay open.

new TextField(
          controller: _controller,
          autocorrect: false,
          autofocus: true
          ...
)

1 回答

  • 2

    在没有看到所有代码的情况下,知道发生了什么有点困难 .

    我最好的猜测是你在TextField上方的某个地方使用上下文来注册继承小部件的更新 .

    我'd advise you to do though is go up the widget tree from your TextField and make sure that you'在上面的任何地方都没有使用继承的小部件 . 可能值得在构建方法的开头放置一些调试语句来确定构建的确切触发位置(如果你正确使用它,继承的小部件不应该在它下面触发重建,但是陌生的东西有发生过) .

    这包括如果您有这样的事情:

    MyWidget extends StatelessWidget {
      Widget build(BuildContext context) {
        Location location = MyInheritedWidget.of(context).location;
        return new Row(
          children: [
            new LocationDisplayer(location),
            new TextField( ..... ),
          ],
        );
      }    
    }
    

    我说这个的原因是我对继承小部件如何工作的理解;当它发生变化时,无论哪个小部件使用其上下文来获取继承的小部件都会重建 .

    这意味着即使你的文本字段在技术上没有改变任何属性,它实际上可能是一个新的文本字段,取决于构建的方式(有一些颤动的魔法,我不完全理解他们如何决定何时制作新的vs重建东西),因此它没有要求重点 .

    我不相信必须编写一些新的小部件来封装使用MyInheritedWidget的任何东西,我相信你可以使用这样的东西:

    MyWidget extends StatelessWidget {
      Widget build(BuildContext context) {
        return new Row(
          children: [
            new Builder(
              builder: (context) {
                Location location = MyInheritedWidget.of(context).location;
                return new LocationDisplayer(location);
              },
            ),
            new TextField( ..... ),
          ],
        );
      }    
    }
    

    如果你没有在任何地方这样做,那么你可以采取不易于处理的方式......你的位置类可以暴露订阅和取消订阅方法 . 您实际使用位置调用的所有小部件(也应该是有状态小部件)在 initState() 中使用回调并在其 dispose() 中取消订阅 . 就像你现在所做的那样,location类只会调用每个回调而不是改变状态,并且在每个回调中你应该为实际显示位置的小部件调用 setState .

相关问题