Flutter在键盘的上方加一个完成按钮

有些情况下,输入框在输入键盘弹出后, 需要在键盘的上方显示一个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) {
      
   })

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值