如何在颤振中检测文本字段是否被选中?

我有一个扑动文本字段,得到覆盖的软键盘时,该领域是选定的。当键盘显示时,我需要向上和向外滚动字段。这是一个非常常见的问题,在 StackOverflow 贴子中提供了一个解决方案。

我认为我有 滚动控制器的部分指出,但我如何检测时,文本字段已被选中?似乎没有任何事件方法(例如 onFocus ()、 onSelected ()、 onTap ()等)。

我尝试将 TextField 包装在 手势检测器中,但这也没有用——显然事件从未被捕获。

new GestureDetector(
child: new TextField(
decoration: const InputDecoration(labelText: 'City'),
),
onTap: () => print('Text Selected'),
),

这是一个如此基本的要求,我知道必须有一个简单的解决方案。

79935 次浏览

I suppose you are looking for FocusNode.

To listen to focus change, you can add a listner to the FocusNode and specify the focusNode to TextField.

Example:

class TextFieldFocus extends StatefulWidget {
@override
_TextFieldFocusState createState() => _TextFieldFocusState();
}


class _TextFieldFocusState extends State<TextFieldFocus> {
FocusNode _focus = FocusNode();


TextEditingController _controller = TextEditingController();


@override
void initState() {
super.initState();
_focus.addListener(_onFocusChange);
}


@override
void dispose() {
super.dispose();
_focus.removeListener(_onFocusChange);
_focus.dispose();
}


void _onFocusChange() {
debugPrint("Focus: ${_focus.hasFocus.toString()}");
}
  

@override
Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new TextField(
focusNode: _focus,
),
);
}
}

This gist represents how to ensure a focused node to be visible on the ui.

Hope it helps!

The easiest and simplest solution is to add the onTap method on TextField.

TextField(
onTap: () {
print('Editing stated $widget');
},
)

To be notified about a focus event, you can avoid manually managing widget's state, by using the utility classes FocusScope, Focus.

From the docs (https://api.flutter.dev/flutter/widgets/FocusNode-class.html):

Please see the Focus and FocusScope widgets, which are utility widgets that manage their own FocusNodes and FocusScopeNodes, respectively. If they aren't appropriate, FocusNodes can be managed directly.

Here is a simple example:

FocusScope(
child: Focus(
onFocusChange: (focus) => print("focus: $focus"),
child: TextField(
decoration: const InputDecoration(labelText: 'City'),
)
)
)

There is another way if your textfield needs to be disabled for some purpose like mine. for that case, you can wrap your textField with InkWell like this,

InkWell(
onTap: () {
print('clicked');
},
child: TextField(
enabled: false,
),
);