有些情况下,输入框在输入键盘弹出后, 需要在键盘的上方显示一个toolbar , 然后 toolbar 上面一个完成按钮,点完成按钮把键盘关闭。
如图:
直接上代码,这样写的好处是,把 TextField 给封装了, 这样使用起来更方便一些,
更多的属性,自己可以在上面扩展。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class KeyboardDoneInput extends StatefulWidget {
final TextEditingController controller;
final ValueChanged<String>? onSubmitted;
const KeyboardDoneInput({
Key? key,
required this.controller,
this.onSubmitted,
}) : super(key: key);
@override
State<KeyboardDoneInput> createState() => _KeyboardDoneInputState();
}
class _KeyboardDoneInputState extends State<KeyboardDoneInput> {
late final FocusNode _focusNode = FocusNode();
OverlayEntry? _overlayEntry;
@override
void initState() {
super.initState();
_focusNode.addListener(_handleFocusChange);
}
void _handleFocusChange() {
if (_focusNode.hasFocus) {
_insertOverlay();
} else {
_removeOverlay();
}
}
void _insertOverlay() {
if (_overlayEntry != null) return;
final overlay = Overlay.of(context);
_overlayEntry = OverlayEntry(
builder: (context) => Positioned(
left: 0,
right: 0,
bottom: MediaQuery.of(context).viewInsets.bottom,
child: Material(
color: Colors.transparent,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
color: Colors.grey[100],
child: Row(
children: [
const Spacer(),
CupertinoButton(
padding: EdgeInsets.zero,
child: const Text(
"完成",
style: TextStyle(fontSize: 16, color: Colors.black),
),
onPressed: () {
_focusNode.unfocus();
widget.onSubmitted?.call(widget.controller.text);
},
),
],
),
),
),
),
);
overlay.insert(_overlayEntry!);
}
void _removeOverlay() {
_overlayEntry?.remove();
_overlayEntry = null;
}
@override
void dispose() {
_focusNode.dispose();
_removeOverlay();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
controller: widget.controller,
focusNode: _focusNode,
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
decoration: const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
),
onSubmitted: widget.onSubmitted,
);
}
}
调用如下,
KeyboardDoneInput(
controller: _controller,
onSubmitted: (value) {
})