背景
Flutter项目中,TextField设置如下属性
keyboardType: TextInputType.number,
textInputAction: TextInputAction.done,
在Android环境下数字键盘会变成Done,在IOS环境下数字键盘无Done按钮。
具体会有什么问题呢:
Android环境下,用户点击Done,可以有效关闭键盘,进行下一步的操作,不阻塞用户流程,体验较好。
IOS环境下无法关闭数字键盘,令人极端焦虑
解决办法
判断IOS设备下,人工增加Done视图
封装通用解决方案,开放设置done布局的接口
import 'package:flutter/cupertino.dart';
///展示关闭键盘按钮
class KeyBoardTools {
OverlayEntry? _overlayEntry;
BuildContext context;
late FocusNode _numberFocusNode;
Widget doneWidget;
KeyBoardTools(this.context, {required this.doneWidget}) {
_numberFocusNode = FocusNode();
}
void initState() {
_numberFocusNode.addListener(() {
if (_numberFocusNode.hasFocus) {
showOverlay();
} else {
removeOverlay();
}
});
}
void dispose() {
_numberFocusNode.dispose();
}
FocusNode get numFocusNode {
return _numberFocusNode;
}
showOverlay() {
if (_overlayEntry != null) return;
OverlayState? overlayState = Overlay.of(context);
if (overlayState == null) {
return;
}
_overlayEntry = OverlayEntry(builder: (context) {
return Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom,
right: 0.0,
left: 0.0,
child: doneWidget);
});
overlayState.insert(_overlayEntry!);
}
removeOverlay() {
if (_overlayEntry != null) {
_overlayEntry!.remove();
_overlayEntry = null;
}
}
}
InputDoneView代码如下:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
///ios键盘done
class InputDoneView extends StatelessWidget {
String doneText;
InputDoneView(this.doneText, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
color: Colors.white,
child: Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4.0),
child: CupertinoButton(
padding: const EdgeInsets.only(right: 24.0, top: 8.0, bottom: 8.0),
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
},
//S.of(context).index30196
child: Text(doneText,
style: const TextStyle(
color: Colors.blueAccent, fontWeight: FontWeight.bold)),
),
),
),
);
}
}
调用示例
KeyBoardTools? _keyBoardTools;
@override
void initState() {
super.initState();
//初始化
if (Platform.isIOS) {
_keyBoardTools = KeyBoardTools(context,
doneWidget: InputDoneView("Done"));
_keyBoardTools?.initState();
}
}
@override
void dispose() {
//销毁
_keyBoardTools?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
maxLines: 1,
strutStyle: const StrutStyle(fontSize: 16),
style:
const TextStyle(color: Color(0xE5000000), height: 1, fontSize: 16),
controller: controller,
keyboardType: TextInputType.number,
keyboardAppearance: Brightness.light,
focusNode: _keyBoardTools?.numFocusNode,
decoration: InputDecoration(
hintText: hintString,
hintStyle: const TextStyle(color: Color(0x42000000), height: 1),
border: InputBorder.none,
),
textAlign: TextAlign.end,
textInputAction: TextInputAction.done,
);
}
可以运行看下效果