我有一个与其连接的文本字段TextEditingController()。在onChanged:回调中,我执行文本检查以仅允许时间输入。当在 iOS 上运行CupertinoTextfield并且其行为符合预期时,每次输入光标都会移动,因此下一个数字位于正确的位置,因此输入 1000 将得到 10:00。当在网络或 Android 上运行Material Textfield时,问题是当光标停留在第一个位置时文本向后显示,因此输入 1000 将导致 00:01 ..我尝试启用autofocus: true,但没有帮助。我尝试过textDirection: TextDirection.ltr,但也没有修复。我还尝试了另一篇文章中的解决方案,抓取控制器选择并将其重新应用到选中的文本上,但它也没有帮助。我缺少为 Material Textfield 设置什么?一如既往,非常感谢您的时间和帮助。
这是小部件:
Expanded(
flex: 2,
child: kIsWeb
? TextField(
keyboardType: TextInputType.numberWithOptions(),
textDirection: TextDirection.ltr,
autofocus: true,
controller: monMorOp,
onChanged: (value) {
TextSelection previousSelection =
monMorOp.selection;
monMorOp.text = validateTimeFormat(value);
monMorOp.selection = previousSelection;
},
)
: Platform.isIOS
? CupertinoTextField(
keyboardType:
TextInputType.numberWithOptions(),
controller: monMorOp,
onChanged: (value) {
monMorOp.text = validateTimeFormat(value);
},
)
: TextField(
keyboardType:
TextInputType.numberWithOptions(),
controller: monMorOp,
onChanged: (value) {
monMorOp.text = validateTimeFormat(value);
},
),
),
Run Code Online (Sandbox Code Playgroud)
这是文本检查方法:
String validateTimeFormat(String value) {
print('call back method called');
// String numb = event.text;
print('input text is $value');
String cleanNumb = value.replaceAll(RegExp(':'), '').substring(0);
print('cleaned input text is $cleanNumb');
RegExp isDigit = RegExp(r'^[\d]{1,4}$'); // is digit 1 to 4 characters
// RegExp isDigit = RegExp(r'^[\d]$'); // is digit
RegExp input;
String text;
int lenght;
String replaced;
if (isDigit.hasMatch(cleanNumb)) {
print('text is 1-4 digits');
text = cleanNumb;
lenght = text.length;
// print('lenght is $lenght');
if (lenght == 1) {
// first digit
//allow 0-2
input = RegExp(r'^[0-2]$');
input.hasMatch(text[0])
? print('text is : $text')
: print('text is: not valid');
return input.hasMatch(text[lenght - 1]) ? text : '';
} else if (lenght == 2) {
// second digit
int first = int.parse(text[0]);
print('firstDigit is $first');
if (first == 008 || first == 1) {
// allow 0-9
input = RegExp(r'^[0-9]$');
input.hasMatch(text[lenght - 1])
? print('text is : $text')
: print('text is : ${text.substring(0, lenght - 1)}');
return input.hasMatch(text[lenght - 1])
? text
: text.substring(0, lenght - 1);
} else {
// allow 0-3
input = RegExp(r'^[0-3]$');
input.hasMatch(text[lenght - 1])
? print('text is : $text')
: print('text is : ${text.substring(0, lenght - 1)}');
return input.hasMatch(text[lenght - 1])
? text
: text.substring(0, lenght - 1);
}
}
if (lenght == 3) {
//third digit
// add : at lenght-1
// allow 0-5
input = RegExp(r'^[0-5]$');
input.hasMatch(text[lenght - 1])
? replaced = text.replaceRange(2, lenght, ':${text.substring(2)}')
: replaced = text.substring(0, lenght - 1);
print('text is : $replaced');
return replaced;
}
if (lenght == 4) {
// fourth digit
// allow 0-9
input = RegExp(r'^[0-9]$');
input.hasMatch(text[lenght - 1])
? replaced = text.replaceRange(2, lenght, ':${text.substring(2)}')
: replaced = text.substring(0, lenght - 1);
print('text is : $replaced');
return replaced;
}
} else {
// discard extra digit
print('more than 4 digits');
lenght = cleanNumb.length;
replaced =
cleanNumb.replaceRange(2, lenght, ':${cleanNumb.substring(2, 4)}');
print('text is : $replaced');
return replaced;
}
}
Run Code Online (Sandbox Code Playgroud)
差不多一个月后,我找到了问题的解决方案,感谢 jwehrle 的回答,如何在文本字段中的颤动中将光标位置设置在值的末尾?。实际上,我向 Flutter 团队提交了一个问题,因为它的行为与向其分配操纵文本时Material Textfield不同,而且它似乎与平台相关,我只在 Web 和 iPad 上测试了它。\n我认为这个解决方案更多的是一种解决方法,因为这应该不是必需的,因为iOS 上不需要。CupertinoTextfieldTextEditingControllerCupertinoTextfield
在onChanged:回调中将操作的输入文本分配给控制器后添加以下内容:
textfieldController.selection = TextSelection.fromPosition(TextPosition(offset: textfieldController.text.length));
Expanded(\n flex: 2,\n child: UniversalPlatform.isWeb\n ? TextField(\n keyboardType: TextInputType.numberWithOptions(),\n textDirection: TextDirection.ltr,\n autofocus: true,\n controller: monMorOp,\n style: TextStyle(\n color: Colors.white,\n fontSize: 15,\n fontWeight: FontWeight.w500),\n onChanged: (value) {\n monMorOp.text = validateTimeFormat(value);\n monMorOp.selection =\n TextSelection.fromPosition(TextPosition(\n offset: monMorOp.text.length));\n },\n )\n : UniversalPlatform.isIOS\n ? CupertinoTextField(\n keyboardType:\n TextInputType.numberWithOptions(),\n controller: monMorOp,\n style: TextStyle(\n color: Colors.white,\n fontSize: 15,\n fontWeight: FontWeight.w500),\n onChanged: (value) {\n monMorOp.text = validateTimeFormat(value);\n },\n )\n : TextField(\n keyboardType:\n TextInputType.numberWithOptions(),\n controller: monMorOp,\n style: TextStyle(\n color: Colors.white,\n fontSize: 15,\n fontWeight: FontWeight.w500),\n onChanged: (value) {\n monMorOp.text = validateTimeFormat(value);\n monMorOp.selection =\n TextSelection.fromPosition(\n TextPosition(\n offset:\n monMorOp.text.length));\n },\n ),\n ),\nRun Code Online (Sandbox Code Playgroud)\n当我升级到 Catalina、Android Studio 4.0 时,iOS 现在也需要解决方法。不确定是否是由于 iOS 13.5 或 Flutter 中的更改所致。但在网络上,它现在会成对打乱数字。\n看起来修复了某些内容,但又破坏了其他内容。
\n[\xe2\x9c\x93] Flutter (Channel master, 1.21.0-8.0.pre.98, on Mac OS X 10.15.4 19E287, locale it-IT)\n \xe2\x80\xa2 Flutter version 1.21.0-8.0.pre.98 at /Users/vinnytwice/Developer/flutter\n \xe2\x80\xa2 Framework revision 77b4505c80 (31 hours ago), 2020-08-06 18:51:02 -0700\n \xe2\x80\xa2 Engine revision cd3ea1e839\n \xe2\x80\xa2 Dart version 2.10.0 (build 2.10.0-3.0.dev fcafd43f2c)\n\n \n[\xe2\x9c\x93] Android toolchain - develop for Android devices (Android SDK version 30.0.1)\n \xe2\x80\xa2 Android SDK at /Users/vinnytwice/Library/Android/sdk\n \xe2\x80\xa2 Platform android-29, build-tools 30.0.1\n \xe2\x80\xa2 Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n \xe2\x80\xa2 Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)\n \xe2\x80\xa2 All Android licenses accepted.\n\n[\xe2\x9c\x93] Xcode - develop for iOS and macOS (Xcode 11.5)\n \xe2\x80\xa2 Xcode at /Volumes/ProjectsSSD/Xcode.app/Contents/Developer\n \xe2\x80\xa2 Xcode 11.5, Build version 11E608c\n \xe2\x80\xa2 CocoaPods version 1.9.3\n\n[\xe2\x9c\x93] Chrome - develop for the web\n \xe2\x80\xa2 Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome\n\n[\xe2\x9c\x93] Android Studio (version 4.0)\n \xe2\x80\xa2 Android Studio at /Applications/Android Studio.app/Contents\n \xe2\x80\xa2 Flutter plugin version 47.1.2\n \xe2\x80\xa2 Dart plugin version 193.7361\n \xe2\x80\xa2 Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)\n\n[\xe2\x9c\x93] Connected device (3 available)\n \xe2\x80\xa2 iPad Pro (12.9-inch) (4th generation) (mobile) \xe2\x80\xa2 08E2351F-A170-4C2E-A8DE-8FED3B5E3124 \xe2\x80\xa2 ios \xe2\x80\xa2\n com.apple.CoreSimulator.SimRuntime.iOS-13-5 (simulator)\n \xe2\x80\xa2 Web Server (web) \xe2\x80\xa2 web-server \xe2\x80\xa2 web-javascript \xe2\x80\xa2 Flutter\n Tools\n \xe2\x80\xa2 Chrome (web) \xe2\x80\xa2 chrome \xe2\x80\xa2 web-javascript \xe2\x80\xa2 Google\n Chrome 84.0.4147.105\n\n\xe2\x80\xa2 No issues found!\nRun Code Online (Sandbox Code Playgroud)\n而不是在文本格式化后将新文本字段的值从onChanged回调分配给它的控制器参数.text
monMorOp.text = validateTimeFormat(value);\nRun Code Online (Sandbox Code Playgroud)\n然后通过偏移控制器的.text.length数量来替换控制器选择:
monMorOp.selection = TextSelection.fromPosition(TextPosition(offset: monMorOp.text.length));\nRun Code Online (Sandbox Code Playgroud)\n现在,我将新的格式化文本字段文本分配给控制器.value,并按文本字段的格式化值偏移其选择位置,如下所示
onChanged: (value) {\n value = validateTimeFormat(value);\n monMorCl.value = TextEditingValue(\n text: value,\n selection: TextSelection.collapsed(offset: value.length));\n },\nRun Code Online (Sandbox Code Playgroud)\n希望它能帮助其他人,因为我发现最近随着 Flutter/Dart 的更新,情况发生了很大的变化。\n干杯
\n| 归档时间: |
|
| 查看次数: |
2438 次 |
| 最近记录: |