材质文本字段文本向后显示,但CupertinoTextfield文本正确显示 [英] Material Textfield text is displayed backwards but CupertinoTextfield text is displayed correctly Flutter

查看:65
本文介绍了材质文本字段文本向后显示,但CupertinoTextfield文本正确显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文本字段连接到它的TextEditingController().在onChanged:回调内部,我执行文本检查以仅允许时间输入. 当在iOS上运行时,使用CupertinoTextfield且其行为符合预期,每个输入光标都会移动,因此下一位数字位于正确的位置,因此输入1000将导致10:00. 相反,当在Web上运行或使用Android Material Textfield时,问题在于,由于光标停留在第一个位置,因此文本向后显示,因此输入1000将导致00:01 .. 我尝试启用autofocus: true,但无济于事.我尝试了textDirection: TextDirection.ltr,,但也没有修复.我还尝试了另一篇文章中的解决方案,它抓住了控制器的选择并将其重新应用于选中的文本,但这也无济于事. 我缺少为材质文本字段"设置什么? 一如既往,非常感谢您的时间和帮助.

I have a textfield connected to its TextEditingController(). Inside the onChanged: callback I perform a text check to only allow for time input. When running on iOS CupertinoTextfield is used and it behaves as expected, at every input cursor moves so next digit is at the right position, so inputting 1000 will result in 10:00. When running on web or Android Material Textfield is used instead, the problem is that text is displayed backward as the cursor stays at first position so inputting 1000 will result in 00:01 .. I tried enabling autofocus: true , but doesn't help. I tried with textDirection: TextDirection.ltr, but didn't fixit either. I also tried a solution from another post here grabbing the controller selection and reapplying it on the checked text but it didn't help either. What am I missing to set for Material Textfield ? As always thank you very much for your time and help.

这是小部件:

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);
                                    },
                                  ),
                      ),

这是文本检查方法:

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;
    }
  }

推荐答案

近一个月后,由于jwehrle在这里回答了问题,我找到了解决问题的方法

After almost a month I found a solution to the problem thanks to jwehrle answer here how to set cursor position at the end of the value in flutter in textfield?. I actually filed an issue to the Flutter team as Material Textfield behaves different from CupertinoTextfield when assigning a manipulated text to its TextEditingController and it seems to be platform related, I only tested it on web and iPad. I think of this solution more of a workaround as this shouldn't be necessary as it isn't needed in CupertinoTextfield on iOS.

onChanged:回调中,将操纵的输入文本分配给控制器后,添加以下内容:

In onChanged: callback add this after assigning the manipulated input text to the controller:

textfieldController.selection = TextSelection.fromPosition(TextPosition(offset: textfieldController.text.length));

Expanded(
                        flex: 2,
                        child: UniversalPlatform.isWeb
                            ? TextField(
                                keyboardType: TextInputType.numberWithOptions(),
                                textDirection: TextDirection.ltr,
                                autofocus: true,
                                controller: monMorOp,
                                style: TextStyle(
                                    color: Colors.white,
                                    fontSize: 15,
                                    fontWeight: FontWeight.w500),
                                onChanged: (value) {
                                  monMorOp.text = validateTimeFormat(value);
                                  monMorOp.selection =
                                      TextSelection.fromPosition(TextPosition(
                                          offset: monMorOp.text.length));
                                },
                              )
                            : UniversalPlatform.isIOS
                                ? CupertinoTextField(
                                    keyboardType:
                                        TextInputType.numberWithOptions(),
                                    controller: monMorOp,
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontSize: 15,
                                        fontWeight: FontWeight.w500),
                                    onChanged: (value) {
                                      monMorOp.text = validateTimeFormat(value);
                                    },
                                  )
                                : TextField(
                                    keyboardType:
                                        TextInputType.numberWithOptions(),
                                    controller: monMorOp,
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontSize: 15,
                                        fontWeight: FontWeight.w500),
                                    onChanged: (value) {
                                      monMorOp.text = validateTimeFormat(value);
                                      monMorOp.selection =
                                          TextSelection.fromPosition(
                                              TextPosition(
                                                  offset:
                                                      monMorOp.text.length));
                                    },
                                  ),
                      ),

更新2020年8月8日:

当我升级到Catalina,Android Studio 4.0时,iOS现在也需要解决方法.不确定是否是由于iOS 13.5或Flutter ..的更改所致.但是在网络上,它现在成对出现乱码. 看起来像是固定的东西而破碎的东西.

update 8 aug 2020:

As I upgraded to Catalina, Android Studio 4.0 the workaround is now needed also for iOS. Not sure if it's due to a change in iOS 13.5 or Flutter.. but on web it now scrambles digits in pair.. Looks like the fixed something and broken something else..

[✓] Flutter (Channel master, 1.21.0-8.0.pre.98, on Mac OS X 10.15.4 19E287, locale it-IT)
    • Flutter version 1.21.0-8.0.pre.98 at /Users/vinnytwice/Developer/flutter
    • Framework revision 77b4505c80 (31 hours ago), 2020-08-06 18:51:02 -0700
    • Engine revision cd3ea1e839
    • Dart version 2.10.0 (build 2.10.0-3.0.dev fcafd43f2c)

 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
    • Android SDK at /Users/vinnytwice/Library/Android/sdk
    • Platform android-29, build-tools 30.0.1
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.5)
    • Xcode at /Volumes/ProjectsSSD/Xcode.app/Contents/Developer
    • Xcode 11.5, Build version 11E608c
    • CocoaPods version 1.9.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 47.1.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[✓] Connected device (3 available)
    • iPad Pro (12.9-inch) (4th generation) (mobile) • 08E2351F-A170-4C2E-A8DE-8FED3B5E3124 • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-13-5 (simulator)
    • Web Server (web)                               • web-server                           • web-javascript • Flutter
      Tools
    • Chrome (web)                                   • chrome                               • web-javascript • Google
      Chrome 84.0.4147.105

• No issues found!

这篇关于材质文本字段文本向后显示,但CupertinoTextfield文本正确显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆