首页 > 解决方案 > 在多行文本字段颤动上插入逗号

问题描述

用户按下键盘上的回车键后,我需要添加一个逗号。我正在使用多行文本字段。

这是我的代码:

TextField(
            textCapitalization: TextCapitalization.words,
            textInputAction: TextInputAction.newline,
            controller: ExpressTextController,
            autofocus: true,
            maxLines: 10,
            decoration: InputDecoration(
                     hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
            style: TextStyle(
              fontSize: 18,
            ),
            keyboardType: TextInputType.multiline,
          ),

标签: flutter

解决方案


您可以使用TextInputFormatter. 在您的TextField中,设置其inputFormatters属性。

TextField(
  ...
  inputFormatters: [CommaNewLineInputFormatter()],
),

这是您的方案的示例格式化程序。

class CommaNewLineInputFormatter extends TextInputFormatter {
  final StringBuffer _newText = StringBuffer();
  final List<int> _separatorCodeUnits = '\n,'.codeUnits;

  bool _useOldValueNext = false;

  int get _newLineCodeUnit => _separatorCodeUnits.first;

  int get _commaCodeUnit => _separatorCodeUnits.last;

  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue,
    TextEditingValue newValue,
  ) {
    if (_useOldValueNext) {
      _useOldValueNext = false;
      return oldValue;
    }

    final int selectionIdx = newValue.selection.baseOffset - 1;
    final int selectionCodeUnit = newValue.text.codeUnitAt(selectionIdx);

    if (newValue.text.length < oldValue.text.length) {
      int minusSelectionOffset = 0;
      _newText.clear();

      if (selectionCodeUnit == _newLineCodeUnit) {
        _newText.write(newValue.text);
        _useOldValueNext = true;
      } else if (selectionCodeUnit == _commaCodeUnit) {
        _newText.writeAll([
          newValue.text.substring(0, selectionIdx),
          newValue.text.substring(selectionIdx + 1),
        ]);
        minusSelectionOffset = 1;
        _useOldValueNext = true;
      } else {
        return newValue;
      }

      return newValue.copyWith(
        text: _newText.toString(),
        selection: newValue.selection.copyWith(
          baseOffset: newValue.selection.baseOffset - minusSelectionOffset,
          extentOffset: newValue.selection.extentOffset - minusSelectionOffset,
        ),
      );
    } else if (selectionCodeUnit == _newLineCodeUnit ||
        selectionCodeUnit == _commaCodeUnit) {
      final int prevCharCodeUnit = newValue.text.codeUnitAt(selectionIdx - 1);
      final bool isPrevCharSeparator = prevCharCodeUnit == _newLineCodeUnit ||
          prevCharCodeUnit == _commaCodeUnit;
      int addSelectionOffset = 1;

      if (selectionCodeUnit == _newLineCodeUnit &&
          prevCharCodeUnit == _newLineCodeUnit) {
        // Do not move cursor if previous and new character is a new line
        // because the new character won't be added.
        addSelectionOffset = -1;
      } else if (isPrevCharSeparator) {
        // Move cursor by 1 if "," is typed after a "," in the TextField.
        addSelectionOffset = 0;
      }

      _newText.clear();
      _newText.writeAll([
        newValue.text.substring(0, selectionIdx),
        if (!isPrevCharSeparator) ',\n',
        newValue.text.substring(selectionIdx + 1),
      ]);

      return newValue.copyWith(
        text: _newText.toString(),
        selection: newValue.selection.copyWith(
          baseOffset: newValue.selection.baseOffset + addSelectionOffset,
          extentOffset: newValue.selection.extentOffset + addSelectionOffset,
        ),
      );
    }

    return newValue;
  }
}

推荐阅读