flutter web 中 textField 添加suffixIcon后输入中文时会多一个首字母

639 阅读1分钟

问题现象

这个问题在本地开发时没有,在打包发布后会出现, 具体表现如下:

image.png

在通过拼音输入“安徽区”拼音后,输入框会多一个首字符“a”

问题原因

应该是添加了suffixIcon (右侧的X图标),这个图标显示的逻辑是有字符输入后才显示,

    _searchController.addListener(() {
      setState(() {
        inputText = _searchController.text;
      });
    });

在有字符变化后这里通过监听直接打断了输入,提前截取了输入的字符

但是本地跑没有问题,所以也有可能是跟浏览器引擎有关系

解决方案

看是如何解决的吧,也是稀里糊涂解决的

import 'package:flutter/material.dart';

class SearchBar extends StatefulWidget {
  double? searchWidth;
  String? hintText;
  Function(String?)? onChanged;
  Function(String)? touchSearch;
  SearchBar(
      {this.hintText,
      this.searchWidth,
      this.onChanged,
      this.touchSearch,
      super.key});

  @override
  State<SearchBar> createState() => _SearchBarState();
}

class _SearchBarState extends State<SearchBar> {
  TextEditingController _searchController = TextEditingController();
  FocusNode focusNode = FocusNode();
  bool canSearch = false;
  bool isFocus = false;
  String inputText = '';

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    focusNode.addListener(() {
      setState(() {
        isFocus = focusNode.hasFocus;
      });
      if (!focusNode.hasFocus) {
        if (widget.touchSearch != null) {
          widget.touchSearch!(inputText);
        }
      }
    });

    _searchController.addListener(() {
      setState(() {
        inputText = _searchController.text;
      });
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _searchController.dispose();
    focusNode.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        children: [
          Container(
            width: widget.searchWidth ?? 400,
            height: 32,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8),
              color: Color(0xFFF4F6FA),
              border: Border.all(
                  width: 0.5,
                  color: isFocus ? Color(0xFF2B66D9) : Color(0xFFE6E8EB)),
            ),
            child: TextField(
              focusNode: focusNode,
              controller: _searchController,
              style: const TextStyle(
                fontSize: 14,
                color: Color(0xFF020F22),
                fontWeight: FontWeight.w400,
              ),
              cursorColor: const Color(0xFF007AFF),
              cursorWidth: 1,
              decoration: InputDecoration(
                isCollapsed: true,
                contentPadding:
                    EdgeInsets.symmetric(horizontal: 14, vertical: 10),
                // focusColor: const Color(0xFF2B66D9),
                hintText: widget.hintText ?? '',
                hintStyle: TextStyle(
                  fontSize: 14,
                  color: Color(0xFFA4ABB0),
                  fontWeight: FontWeight.w400,
                ),
                focusedBorder: InputBorder.none,
                border: InputBorder.none,
                prefixIcon: Container(
                  alignment: Alignment.center,
                  child: Image.asset(
                    'assets/images/search.png',
                    width: 18,
                    height: 18,
                  ),
                ),
                prefixIconConstraints: BoxConstraints(
                  maxHeight: 18,
                  maxWidth: 36,
                ),
                suffixIcon: inputText.isNotEmpty
                    ? IconButton(
                        onPressed: () {
                          _searchController.clear();
                          if (widget.onChanged != null) {
                            widget.onChanged!('');
                          }
                        },
                        icon: const Image(
                          image: AssetImage("assets/images/ic_input_close.png"),
                          width: 16,
                          height: 16,
                        ))
                    : Container(
                        width: 16,
                        height: 16,
                      ),
              ),
              onChanged: (String? text) {
                if (widget.onChanged != null) {
                  widget.onChanged!(text);
                }
                if (text != null && text.isNotEmpty) {
                  setState(() {
                    canSearch = true;
                  });
                } else {
                  setState(() {
                    canSearch = false;
                  });
                }
              },
            ),
          ),
        ],
      ),
    );
  }

}