Flutter文本框值始终大写且防抖动。

82

我是Flutter的新手。我想让文本框中的值始终为大写,但我没有找到相关的资源。

另一个问题是TextField onChanged事件的防抖实现。当我在TextField上输入时,它会立即触发onChanged事件,这对我的目标不太适用。onChange事件将在每次更改文本后的500毫秒后触发。

 new TextField(
         controller: _controller,
         decoration: new InputDecoration(
              hintText: 'Search here',
         ),
         onChanged: (str) {
            //need to implement debounce
         }
)

1
你想要将第一个字符或所有文本大写吗?你可以使用来自 https://github.com/ReactiveX/rxdart 的 debounce。 - Günter Zöchbauer
需要将所有字符转换为大写字母。@GünterZöchbauer - Harun
1
你的问题涉及到TextField的两个不同方面。下次请分开提问。我拒绝在一个本来不错的问题上点赞。 - Michael Ribbons
15个回答

226

适用于Android、iOS、Web、macOS、Windows和Linux

您可以实现自定义TextInputFormatter

class UpperCaseTextFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    return TextEditingValue(
      text: newValue.text.toUpperCase(),
      selection: newValue.selection,
    );
  }
}

用法:

TextField(
  inputFormatters: [
    UpperCaseTextFormatter(),
  ]
)

完整示例


10
我不知道为什么这个解决方案没有更多的赞。据我所知,这是实现自动大写格式(或任何类型的文本字段格式)的正确方法。 - Abion47
2
这就是我所说的“高质量”解决方案,与其他解决方案不同,它可以在任何平台上运行,谢谢 :) - CopsOnRoad
2
当启用键盘自动更正时,此答案会导致错误(它将OldValue与NewValue附加在一起)。例如:我想要输入“键盘”这个单词,首先输入字母K,然后输入字母E,但现在它会替换为KKE,以此类推,每次输入一个字母时,它都会将OldValue与NewValue附加在一起。 - rjkolli7
1
完美。textCapitalization: TextCapitalization.characters, 在Windows上不起作用,所以这是一个很好的解决方案。 - West
2
这个解决方案遇到了一个新的Android键盘问题。它在追加而不是替换。需要更新。 - jbryanh
显示剩余11条评论

111

也许在TextField中使用textCapitalization: TextCapitalization.characters会有帮助?不过这也会在输入时将字符大写。

TextField(
    textCapitalization: TextCapitalization.sentences,
)

@praveenb,textCapitalization.sentences 在输入文本字段时无法完全工作,或者值无法大写?每个句子的第一个单词仅大写,并在每个句号(.)后激活。 - petras J
1
是的,我的错误...我发现如果我在文本字段中输入文本,它会自动大写。以前,我预填了一些文本,但大写没有生效。我以为应该会生效。感谢您的澄清 :) - praveenb

55
你可以使用TextField小部件的textCapitalization属性。获取详细的API信息请参考这里:文本大写官方API 示例如下: 例1
 TextField(
        initialValue: flutter code camp
        textCapitalization: TextCapitalization.characters,
    )// OUTPUT : FLUTTER CODE CAMP

例子 2

 TextField(
        initialValue: flutter code camp
        textCapitalization: TextCapitalization.words,
    )// OUTPUT : Flutter Code Camp

例子 3

 TextField(
        initialValue: flutter code camp
        textCapitalization: TextCapitalization.sentences,
    )// OUTPUT : Flutter code camp

示例 4

 TextField(
        initialValue: flutter code camp
        textCapitalization: TextCapitalization.none,
    )// OUTPUT : flutter code camp

28

你需要做的一切是:

在字符串后面加上.toUpperCase()

例如: "Some text".toUpperCase()

这对我的情况有效。我也是新手,所以希望能有所帮助。


3
这是关于一个文本输入框的内容。无法更改任何字符串。使用TextEditingController获取给定的文本,应该在每次按键时用它来修改输入框中的文本。我认为这是不可能的。 - Daniel Leiszen

19

您可以使用 TextCapitalization.characters 将所有输入的字符变为大写字母

TextField(
    textCapitalization: TextCapitalization.characters,
)

2
不好的原因是它只是将用户的键盘切换为大写,但用户可以切换回小写。格式化程序解决方案要好得多。 - kashlo
同时,在MacOS上没有任何影响。 - Ber

10

@Günter-Zöchbauer的解决方案可行,但当您在Android上切换到数字键盘时,如果您键入数字1,则会再次切换到字母键盘。

这是因为您每次都设置了一个新的TextEditingValue。

相反,如果您复制最新的值并更改文本,则可以解决问题:

import 'package:flutter/services.dart';

class UpperCaseTextFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    return newValue.copyWith(text: newValue.text.toUpperCase());
  }
}

1
尽管这个解决方案仍然在控制台中打印出“框架更改了组合区域。重新启动输入法。”,但数字键盘(以及按住退格键)的问题已经得到解决。谢谢! - Bruno Kinast

7

TextField有一个textCapitalization属性,您可以使用它来大写单词、句子或字符。

如果您希望将文本输入的整个值大写,请使用

TextField(
  textCapitalization: TextCapitalization.characters,
 )

我无法在评论中发布完整的代码,但如果您有一个简单的Flutter应用程序并添加一个文本字段,您可以轻松地在Flutter桌面上验证此操作。 - West

7

最简单的方法是添加TextField的onChanged事件,并使用TextField的控制器将文本转换为大写,就像上述代码一样:

TextField(
          controller: controllerReservation,
          onChanged: (value) {               
            controllerReservation.value = 
               TextEditingValue(
                                text: value.toUpperCase(), 
                                selection: controllerReservation.selection);
          },
        )

4
这将移动光标位置到开头。 - Wahyu
@Wahyu 我很确定在发布这个答案时已经测试过了,没有出现问题。但如果需要的话,我会再次测试并发布改进版本。 - Diego Garcia
@DiegoGarcia,我刚刚使用了你的代码示例,它确实将光标设置到字符串的开头并反转了字符串。 - Paul Stoner
1
@PaulStoner 抱歉回复晚了,我已经编辑并修复了!! - Diego Garcia
1
这是命令式思维。Flutter 则完全相反。 - Daniel Leiszen

2

以下是如何在输入文本上实现去抖(或延迟)效果:

1)导入包

rxdart: ^0.18.1 (or whatever the version will be)

2)在您的Stateful Widget中声明以下内容

final subject = new PublishSubject<String>();

3) 在同一个 Stateful Widget 中,在 initState 方法下声明以下内容:

subject.stream
    .debounce(new Duration(milliseconds: 500))
    .listen(_loadNewData);

4)在同一个Stateful Widget中,创建以下方法(将在500毫秒后触发)

  void _loadNewData(String newData) {
    //do update here
  }

4) 在您的文本字段小部件中添加以下行(现在可以摆脱控制器)

onChanged: (string) => (subject.add(string)),

2
将以下代码添加到您的TextFormField中。
 inputFormatters: [UpperCaseTextFormatter()],
 textCapitalization: TextCapitalization.characters,

完整代码

  TextFormField(
      autofillHints: [AutofillHints.name],
      inputFormatters: [UpperCaseTextFormatter()],
      textCapitalization: TextCapitalization.characters,
      textInputAction: TextInputAction.next,
      style: TextStyle(fontSize: 20),
      decoration: InputDecoration(
      contentPadding: EdgeInsets.symmetric(
      horizontal: 0, vertical: 0),
      labelText: "Hello World",
      hintText: '',
    ),
 ),

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接