import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:makemoney/utils/ui_constant.dart'; import 'refresh_listview.dart'; ///SOS雷达扫描View class VerificationBox extends StatefulWidget { final int length; final double width; final VerificationBoxController controller; VerificationBox(this.length, this.controller, {required this.width}); @override _VerificationBoxState createState() => _VerificationBoxState(); } class _VerificationBoxState extends State with WidgetsBindingObserver { final TextEditingController _controller = TextEditingController(); String content = ""; final FocusNode _focusNode = FocusNode(); bool isKeyboardActived = false; @override void initState() { super.initState(); WidgetsBinding.instance!.addObserver(this); widget.controller.controller = _controller; _controller.addListener(() { setState(() { print("listener:"); if (content != _controller.text) { content = _controller.text; if (content.length >= widget.length) { if (content.length > widget.length) { _controller.text = (_controller.text.substring(0, widget.length)); } isKeyboardActived = false; _focusNode.unfocus(); } } }); }); } @override void dispose() { super.dispose(); WidgetsBinding.instance!.removeObserver(this); isKeyboardActived = false; _focusNode.unfocus(); } @override void didChangeMetrics() { print("didChangeMetrics isKeyboardActived:$isKeyboardActived"); super.didChangeMetrics(); WidgetsBinding.instance!.addPostFrameCallback((_) { // 当前是安卓系统并且在焦点聚焦的情况下 if (Platform.isAndroid && _focusNode.hasFocus) { if (isKeyboardActived) { isKeyboardActived = false; // 使输入框失去焦点 _focusNode.unfocus(); return; } isKeyboardActived = true; } }); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () { print("点击事件,输入框获取焦点:${_focusNode.hasFocus}"); FocusScope.of(context).requestFocus(_focusNode); }, child: Stack( children: [ SizedBox( width: 10, child: TextField( cursorHeight: 0, cursorWidth: 0, cursorColor: Colors.transparent, keyboardType: TextInputType.text, inputFormatters: [ FilteringTextInputFormatter.allow( RegExp("[a-zA-Z]|[0-9]")), LengthLimitingTextInputFormatter(widget.length), ], style: const TextStyle(fontSize: 1, color: Colors.transparent), decoration: const InputDecoration( border: InputBorder.none, focusedBorder: InputBorder.none, focusColor: Colors.transparent), textInputAction: TextInputAction.done, focusNode: _focusNode, autofocus: false, controller: _controller)), SizedBox( width: widget.width, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: getItems(), )) ], )); } List getItems() { List list = []; for (int i = 0; i < widget.length; i++) { list.add(getItem(i)); } return list; } Widget getItem(int index) { double width = (widget.width - 10 * widget.length - 1) / widget.length; //TODO 传入宽度计算 return Container( alignment: Alignment.center, width: width, height: width * 1.25, decoration: BoxDecoration( color: const Color(0xFFEFEFEF), borderRadius: BorderRadius.circular(13)), child: Text( content.length >= index + 1 ? content.substring(index, index + 1) : "", style: const TextStyle( color: ColorConstant.theme, fontSize: 24, fontWeight: FontWeight.bold), ), ); } } class VerificationBoxController { VerificationBoxController(); TextEditingController? _controller; set controller(TextEditingController? controller) { _controller = controller; } String get text => (_controller == null ? "" : _controller!.text); set text(String newText) { if (_controller != null) { _controller!.text = (newText); } } }