每当设置新位置时,我都会使用应用程序顶部继承的小部件来更新我的应用程序。这会导致我的应用程序中每个可能的位置刷新我的位置坐标。
但是我也有一个文本字段。当我几秒钟后点击文本字段时 键盘将通过继承的小部件的更新而隐藏。 有没有办法防止抖动隐藏键盘或重新初始化状态,以便继承的小部件的更新与我的搜索字段一起工作? 也有可能当我输入一些文本时,这会触发继承的小部件进行新更新,但搜索栏和键盘应保持打开状态。
new TextField(
controller: _controller,
autocorrect: false,
autofocus: true
...
)
最佳答案
如果不查看所有代码,就很难知道发生了什么。
我最好的猜测是,您正在使用 TextField 上方的上下文来注册继承的小部件的更新。
我建议您从 TextField 进入小部件树,并确保您没有在其上方的上下文中使用继承的小部件。可能值得在构建方法的开头放置一些调试语句,以确定从何处触发构建(如果您使用的是继承的小部件不应该立即在其下面触发重建没错,但是奇怪的事情发生了)。
这包括如果您有这样的事情:
MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
Location location = MyInheritedWidget.of(context).location;
return new Row(
children: [
new LocationDisplayer(location),
new TextField( ..... ),
],
);
}
}
我这么说的原因是根据我对继承小部件如何工作的理解;当它发生变化时,其上下文用于获取继承的小部件的任何小部件都会被重建。
这意味着,即使您的文本字段在技术上没有更改任何属性,它实际上可能是一个新的文本字段,具体取决于构建的方式(有一些 flutter 的魔力,我不完全理解他们如何决定何时制作新东西还是重建东西),因此它没有请求焦点。
我相信您可以使用这样的东西,而不是编写一堆新的小部件来封装使用 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( ..... ),
],
);
}
}
如果您 100% 确定您没有在任何地方执行此操作,那么您可以采用非 flutter 的处理方式...您的位置类可以公开订阅和取消订阅方法。您实际使用位置的所有小部件都在其 initState()
中调用订阅(也应该是有状态小部件)并在其 dispose()
中取消订阅>。位置类将简单地调用每个回调,而不是像您现在所做的那样更改状态,并且在每个回调中,您应该为实际显示位置的小部件调用 setState
。
关于flutter - InheritedWidget更新导致问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49435068/