Flutter:通过按下后退按钮解除键盘时,不关注文本字段(多行)
Posted
技术标签:
【中文标题】Flutter:通过按下后退按钮解除键盘时,不关注文本字段(多行)【英文标题】:Flutter: Unfocus on textfield (multiline) when keyboard is dismissed via back button press 【发布时间】:2020-01-10 04:12:26 【问题描述】:我有以下TextFormField
:
TextFormField(
focusNode: inputFocusNode,
keyboardType: TextInputType.multiline,
maxLines: null,
minLines: 3,
)
当文本字段处于焦点时,会出现键盘。当按下电话返回按钮时,键盘消失,但文本字段上的光标仍然存在。
我知道您可以使用FocusScope.of(context).unfocus()
来移除光标或取消焦点。但是,似乎没有直接的方法来检测键盘关闭而不获得package
我该如何解决这个问题?
【问题讨论】:
我很困惑兄弟,因为每次您按下设备中的后退按钮时,它肯定会关闭设备键盘,但如果您想通过在键盘外单击来关闭它,您可以使用 FocusScope.of(context) .requestFocus(new FocusNode());并将其包装在 GestureDetector() 中并设置在 onTap 上。 或 FocusScope.of(context).unfocus(); 您好,谢谢您的回复。就像你说的,当按下设备后退按钮时,键盘肯定会被关闭(就像我在我的问题中提到的那样)。但是,除非我点击文本字段以外的其他内容,否则文本字段中的光标不会消失。当键盘被关闭时,我试图摆脱闪烁的光标。 例如,我可以用onTap
和unfocus
的文本字段创建一个gesturedetector
。但这依赖于屏幕上的tapping
。但是,当用户通过按下设备后退按钮关闭键盘时,从技术上讲,用户并没有在屏幕上tap
任何内容,因此不会关闭焦点,即使键盘已关闭。
您好,您在这个问题上有什么进展吗?我也有这个问题,不想用包。
【参考方案1】:
作为一个选项,您可以监听窗口指标的变化。
-
给State类添加
WidgetsBindingObserver
接口
覆盖didChangeMetrics
方法
在initState
和dispose
方法中添加/删除监听器
查看完整代码:
import 'package:flutter/material.dart';
void main()
runApp(MaterialApp(home: Scaffold(body: Home())));
class Home extends StatefulWidget
@override
_HomeState createState() => _HomeState();
class _HomeState extends State<Home> with WidgetsBindingObserver
final FocusNode inputFocusNode = FocusNode();
@override
void initState()
super.initState();
WidgetsBinding.instance.addObserver(this);
@override
Widget build(BuildContext context)
return Center(
child: TextFormField(
focusNode: inputFocusNode,
keyboardType: TextInputType.multiline,
maxLines: null,
minLines: 3,
),
);
@override
void didChangeMetrics()
super.didChangeMetrics();
final value = WidgetsBinding.instance.window.viewInsets.bottom;
if (value == 0)
inputFocusNode.unfocus();
@override
void dispose()
WidgetsBinding.instance.removeObserver(this);
inputFocusNode.dispose();
super.dispose();
【讨论】:
【参考方案2】:用这个小部件包裹你的整个应用程序。
Listener(
onPointerDown: (_)
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus &&
currentFocus.focusedChild != null)
currentFocus.focusedChild.unfocus();
,
child: //MyApp()
)
当用户点击其他任何地方时,它也会移除焦点和光标。
【讨论】:
你知道为什么它需要成为整个应用程序的父级吗?我尝试将它放在树中的较低级别,但它不起作用 令人惊讶的是,这个“Listener”小部件做了“GestureDetector”无法实现的事情。这应该被标记为答案。谢谢大佬。【参考方案3】:您可以检查是否可见键盘,当它不可见时,您可以调用unfocus()
方法。例如,要跟踪键盘,您可以使用这个库keyboard_visibility。示例代码:
FocusNode myFocusNode = FocusNode();
KeyboardVisibilityNotification().addNewListener(
onChange: (bool visible)
if (!visible)
myFocusNode.unfocus()
,
);
【讨论】:
【参考方案4】:我将其发布为答案,因为由于我的回购,我仍然无法发表评论。 对我来说@user10539074 的解决方案不起作用,因为它没有让文本字段只聚焦(键盘在尝试打开时立即关闭)。所以我添加了这条额外的行,它对我有用。
if (MediaQuery.of(context).viewInsets.bottom != 0)
if (value == 0)
inputFocusNode.unfocus();
此检查的基本作用是仅在键盘已打开时才运行该代码。
【讨论】:
以上是关于Flutter:通过按下后退按钮解除键盘时,不关注文本字段(多行)的主要内容,如果未能解决你的问题,请参考以下文章