【发布时间】:2020-03-13 07:46:14
【问题描述】:
如何在暂时禁用文本字段的同时保持键盘在屏幕上?
CupertinoTextField 在enabled=false 或readOnly=true 时关闭键盘。我需要将键盘保持在屏幕上。
【问题讨论】:
标签: flutter mobile soft-keyboard
如何在暂时禁用文本字段的同时保持键盘在屏幕上?
CupertinoTextField 在enabled=false 或readOnly=true 时关闭键盘。我需要将键盘保持在屏幕上。
【问题讨论】:
标签: flutter mobile soft-keyboard
我搜索了大约四个小时,终于想出了一个解决方案:让文本字段的onChanged 函数聚焦一个接受键盘输入的隐藏小部件。处理完成后,再次聚焦文本字段。
工作示例:
import 'package:flutter/cupertino.dart'
show
CupertinoApp,
CupertinoButton,
CupertinoPageScaffold,
CupertinoTextField;
import 'package:flutter/widgets.dart'
show
BuildContext,
Center,
ClipRect,
Column,
Container,
FocusNode,
FocusScope,
MainAxisSize,
runApp,
State,
StatefulWidget,
Text,
TextAlign,
TextEditingController,
Widget;
import 'package:meta/meta.dart' show required;
class KeepKeyboardOnScreen extends StatefulWidget {
final FocusNode focusNode;
const KeepKeyboardOnScreen({@required this.focusNode});
@override
State createState() => KeepKeyboardOnScreenState();
}
class KeepKeyboardOnScreenState extends State<KeepKeyboardOnScreen> {
TextEditingController _controller;
@override
void initState() {
super.initState();
_controller = new TextEditingController();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => Container(
height: 0,
child: ClipRect(
child: CupertinoTextField(
controller: _controller,
focusNode: widget.focusNode,
onChanged: (_) => _controller.clear(),
),
),
);
}
class Page extends StatefulWidget {
@override
State createState() => PageState();
}
class PageState extends State<Page> {
TextEditingController _controller;
FocusNode _focusNode;
FocusNode _keepKeyboardOnScreenFocusNode;
bool enabled = true;
@override
void initState() {
super.initState();
_controller = new TextEditingController();
_focusNode = new FocusNode();
_keepKeyboardOnScreenFocusNode = new FocusNode();
}
@override
void dispose() {
_controller.dispose();
_focusNode.dispose();
_keepKeyboardOnScreenFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
CupertinoTextField(
controller: _controller,
focusNode: _focusNode,
enabled: enabled,
),
KeepKeyboardOnScreen(focusNode: _keepKeyboardOnScreenFocusNode),
CupertinoButton(
onPressed: () {
setState(() {
enabled = true;
});
FocusScope.of(context).requestFocus(_focusNode);
},
child: Text("Enable", textAlign: TextAlign.center)),
CupertinoButton(
onPressed: () {
setState(() {
enabled = false;
});
FocusScope.of(context)
.requestFocus(_keepKeyboardOnScreenFocusNode);
},
child: Text("Disable", textAlign: TextAlign.center)),
],
),
),
),
);
}
void main() async {
runApp(Page());
}
另请参阅:Flutter Issue #45076 Add high-level documentation and examples on managing keyboard focus.
【讨论】:
CupertinoTextField 构造函数采用keyboardType 参数,默认为TextInputType.text。当 Flutter 聚焦隐藏的小部件时,它会显示该键盘。如果显示不同的键盘,那么它将切换到该键盘。要在屏幕上保留不同的键盘,您必须传递匹配的 keyboardType 值。