flutter textfield word 数量限制

2021-10-18  本文已影响0人  gooddaytoyou

需求

Flutter 实现一个文本输入框,能够计算word的数量,当超过最大数量时,文本框不再输入。

分析

Flutter文本框选用TextField,从"word的数量",想到可以使用LengthLimitingTextInputFormatter, 但是这个formatter并不符合要求,因此需要重新实现下。

实现

MaxWordTextInputFormater.dart

class MaxWordTextInputFormater extends TextInputFormatter {
  final int maxWords;
  final ValueChanged<int>? currentLength;

  MaxWordTextInputFormater({this.maxWords = 1, this.currentLength});

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    int count = 0;
    if (newValue.text.isEmpty) {
      count = 0;
    } else {
      count = newValue.text.trim().split(RegexUtil.spaceOrNewLine).length;
    }
    if (count > maxWords) {
      return oldValue;
    }
    currentLength?.call(count);
    return newValue;
  }
}

TextFieldPage.dart

class TextFieldPage extends StatefulWidget {
  const TextFieldPage({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return TextFieldPageState();
  }
}

class TextFieldPageState extends State<TextFieldPage> {
  final Color _color = const Color(0xFFF5F6F7);
  int _count = 0;
  final int maxWordLength = 6;

  @override
  Widget build(BuildContext context) {
    return buildPage(
        _buildBody(),
        const Text(
          "TextField Max Words Limit",
          style: TextStyle(fontSize: 16, color: Colors.black),
        ));
  }

  Widget _buildBody() {
    return Container(
        color: _color,
        child: Column(children: [
          const SizedBox(
            height: 12,
          ),
          _buildTextField()
        ]));
  }

  Widget _buildTextField() {
    return _buildContain(
      Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Text(
                "TextField",
                style: TextStyle(fontSize: 16, color: Colors.black),
              ),
              _buildCompute(),
            ],
          ),
          TextInputFieldWidget(
            textInputFormatters: [
              FilteringTextInputFormatter.allow(RegExp(r"[a-z\s_-]+")),
              MaxWordTextInputFormater(maxWords: 6, currentLength: chageCount)
            ],
            hintText: "please fill words ",
            maxLines: 4,
            lineHeight: 1.5,
          )
        ],
      ),
    );
  }

  Widget _buildCompute() {
    return RichText(
        text: TextSpan(
            style: const TextStyle(fontSize: 14, color: Color(0xFF909399)),
            children: [
          const TextSpan(text: '('),
          TextSpan(
              text: _count.toString(),
              style: TextStyle(
                  color: _count > 0
                      ? const Color(0xFF5269FF)
                      : const Color(0xFF909399))),
          TextSpan(text: "/${maxWordLength.toString()})"),
        ]));
  }

  void chageCount(int count) {
    setState(() {
      _count = count;
    });
  }

  Scaffold buildPage(
    Widget body,
    Widget? titleWidget,
  ) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(
        toolbarHeight: 40,
        backgroundColor: _color,
        // status bar color
        automaticallyImplyLeading: false,
        systemOverlayStyle: SystemUiOverlayStyle(
            statusBarColor: _color, statusBarIconBrightness: Brightness.dark),
        foregroundColor: _color,
        shadowColor: Colors.transparent,
        title: titleWidget,
      ),
      body: SafeArea(
        child: body,
      ),
    );
  }

  Widget _buildContain(Widget child) {
    return Container(
        padding: const EdgeInsets.all(16),
        margin: const EdgeInsets.only(left: 16, right: 16, top: 12),
        decoration: const BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(12))),
        child: child);
  }
}

效果图

Oct-18-2021 16-53-14.gif

sourcecode

https://github.com/sayhellotogithub/textfield_length_limit_word

参考

https://api.flutter.dev/flutter/material/TextField-class.html

上一篇 下一篇

猜你喜欢

热点阅读