将 TabBarView 中的其他选项卡更改为其他选项卡时,键盘仍然显示
Posted
技术标签:
【中文标题】将 TabBarView 中的其他选项卡更改为其他选项卡时,键盘仍然显示【英文标题】:Keyboard is still showing when changing the to other Tab in a TabBarView 【发布时间】:2019-10-23 06:41:33 【问题描述】:在一个选项卡中,我有一个 TextFormField,而在另一个选项卡中只有一个文本列表。当我选择键盘打开的文本字段时,我跳到第二个选项卡,键盘仍然显示。 我什至可以写,当我回到 Tab 1 时,我明白我为什么要打字了。
您知道如何对第二个选项卡执行操作以将焦点从文本字段中移开吗?
DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('Manage Products'),
bottom: TabBar(tabs: <Widget>[
Tab(icon: Icon(Icons.create), text: 'Create Product'),
Tab(icon: Icon(Icons.list), text: 'My Products'),
]),
),
body: TabBarView(
children: <Widget>[
ProductEditPage(addProduct: addProduct),
ProductListPage(products, updateProduct),
],
)),
);
Tab1
Tab2
求解代码
应用@nick.tdr 建议后,示例代码如下:
class _Test extends State<Test> with TickerProviderStateMixin
TabController _tabController;
@override
void initState()
super.initState();
_tabController = TabController(vsync: this, length: 2);
_tabController.addListener(()
if (_tabController.indexIsChanging)
FocusScope.of(context).requestFocus(new FocusNode());
);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('2 Tabs'),
bottom: TabBar(controller: _tabController, tabs: <Widget>[
Tab(text: 'Tab with Text Field'),
Tab(text: 'Empty Tab'),
]),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
Container(
child: TextFormField(
decoration: InputDecoration(labelText: 'Title'),
),
),
Container()
],
),
);
【问题讨论】:
***.com/a/55314860/122313 感谢@AaronSaunders,但 detach 对我不起作用。 VSC 确实标记为错误代码:“没有为类 'FocusScopeNode' 定义方法 'detach'”。我不得不使用FocusScope.of(context).requestFocus(new FocusNode());
【参考方案1】:
您可以将手势检测器添加到脚手架并移除焦点。但这不适用于标签。对于选项卡,您需要执行以下操作:
controller.addListener(()
if(controller.indexIsChanging)
FocusScope.of(context).detach();
);
controller 是你的标签控制器。希望有帮助
【讨论】:
为此,您需要删除 DefaultTabController 并使用控制器对象 @diegoveloper 我试过了。如果手势检测器是脚手架中主体的根小部件,则在点击选项卡时不会调用其 on tap。这就是为什么我在标签控制器中添加了一个监听器。如果您有更好的方法,请解释。谢谢 感谢@nick.tdr,它运行良好,但有必要对我的代码进行一些调整。我将用我的解决代码编辑我上面的问题。indexIsChanging
仅在单击选项卡按钮时返回 true
。在选项卡之间滑动时,它返回false
。因此,这并不总是有效。
detach()
现在也无效了。【参考方案2】:
我改进了@nick.tdr 的答案。
对于标签,您需要执行以下操作;
controller.addListener(()
if(controller.indexIsChanging)
FocusScope.of(context).unfocus();
);
如果您想在选项卡之间滑动而不是单击选项卡按钮时进行此操作,请尝试以下操作;
controller.addListener(()
FocusScope.of(context).unfocus();
);
控制器是你的标签控制器。
【讨论】:
【参考方案3】:我认为将您的整个 Scaffold
正文包装成 GestureDetector
应该可以解决您的问题。
new Scaffold(
body: new GestureDetector(
onTap: ()
// call this method here to hide keyboard
FocusScope.of(context).requestFocus(new FocusNode());
,
child: new Container(
/*Remaining code goes here*/
)
)
这只是获得了您在从前一个中删除焦点时点击的小部件的焦点。
【讨论】:
感谢 Manmeet!我试过了,但必须按 Tab 主体中的任意位置才能隐藏键盘。按 Tab 后它并没有立即隐藏它。【参考方案4】:对我来说,我发现最好的方法是在didChangeDependencies()
回调中设置的tabChange侦听器上请求一个新的FocusNode
:
在 build() 方法中:
TabBar(
controller: tabController,
.
.
.
),
didChangeDependencies 回调:
@override
void didChangeDependencies()
setState(()
tabController.addListener(handleTabChange);
);
super.didChangeDependencies();
监听器实现:
handleTabChange()
// do whatever handling required first
setState(()
FocusScope.of(context).requestFocus(new FocusNode());
);
【讨论】:
以上是关于将 TabBarView 中的其他选项卡更改为其他选项卡时,键盘仍然显示的主要内容,如果未能解决你的问题,请参考以下文章
Bootstrap nav-tabs 活动颜色为每个 Bootstrap 活动选项卡更改为不同的颜色