【问题标题】:Put cursor at the end of TextField using TextSelection使用 TextSelection 将光标放在 TextField 的末尾
【发布时间】:2020-05-22 17:47:53
【问题描述】:

我想在TextField 上实现一个简单的验证。 我的方法是监听TextFieldonChange事件,应用我的验证,将值设置为controller.text并将controller.selection设置为之前设置值的长度。

Dartpad

对于 123456789 输入的某些原因,TextField 会产生 864213579。在写入即将到来的字符时在开头和结尾之间交替。使用debugPrints,我可以断言选择应该始终位于输入的末尾。

这可能是什么问题?

【问题讨论】:

  • 您应该使用 TextInputFormatter 来验证您的文本。

标签: flutter


【解决方案1】:

为什么不使用 TextInputFormatter?

这是代码。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var controller = TextEditingController();
  final _amountValidator = RegExInputFormatter.withRegex('^\$|^(0|([1-9][0-9]{0,}))(\\.[0-9]{0,})?\$');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(''),
      ),
      body: Builder(
        builder: (context) {
          return 
            Column(
          children: <Widget>[
            TextField(
            inputFormatters: [_amountValidator],
            controller: controller,
            keyboardType: TextInputType.numberWithOptions(
              decimal: true,
              signed: false,
            ),           
          ),
            FlatButton(
              onPressed:(){
                print(controller.text);
              },
              child:Text("Test"),
            )
            ],
          );
        },
      ),
    );
  }
}






class RegExInputFormatter implements TextInputFormatter {
  final RegExp _regExp;

  RegExInputFormatter._(this._regExp);

  factory RegExInputFormatter.withRegex(String regexString) {
    try {
      final regex = RegExp(regexString);
      return RegExInputFormatter._(regex);
    } catch (e) {
      // Something not right with regex string.
      assert(false, e.toString());
      return null;
    }
  }

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    final oldValueValid = _isValid(oldValue.text);
    final newValueValid = _isValid(newValue.text);
    if (oldValueValid && !newValueValid) {
      return oldValue;
    }
    return newValue;
  }

  bool _isValid(String value) {
    try {
      final matches = _regExp.allMatches(value);
      for (Match match in matches) {
        if (match.start == 0 && match.end == value.length) {
          return true;
        }
      }
      return false;
    } catch (e) {
      // Invalid regex
      assert(false, e.toString());
      return true;
    }
  }
}

参考号:Flutter TextField input only decimal numbers

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 2020-01-27
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多