[Flutter/Dart]: 如何在表单中动态更改TextFormField的键盘类型?

7

我有一个小部件,它呈现了一个ListView的TextFormFields来输入数据。然而,我想动态地改变其中一个文本字段的键盘类型。以下是该小部件的概述:


class CreateTodo extends StatefulWidget {
  @override
  _CreateTodoState createState() => _CreateTodoState();
}

class _CreateTodoState extends State<CreateTodo> {
  final _formKey = GlobalKey<FormState>();
  final double formWidth = 175.0;

  final Map<String, Icon> itemsMap = {
    'Heading': Icon(Icons.title),
    'Description': Icon(Icons.edit),
    'Date': Icon(Icons.calendar_today)
  };

  final items = ['Heading', 'Description', 'Date'];

  _changeKeyboardType(entry) {
    if (entry == "Description") {
      return TextInputType.multiline;
    }

    return TextInputType.text;
  }

  ListView createListItems() {
    return ListView.builder(
      padding: EdgeInsets.only(
        left: 50.0,
        right: 50.0,
        top: 20.0
      ),
      scrollDirection: Axis.vertical,
      itemCount: 3,
      itemBuilder: (context, index) {
        var currentHeading = this.items[index];
        var currentIcon = this.itemsMap[currentHeading];

        return Padding(
          padding: EdgeInsets.only(bottom: 50.0),
          child: new TextFormField(
              validator: (input) {
                if (input.isEmpty) {
                  return 'You must enter a ${currentHeading.toLowerCase()} for your to-do';
                }
              },
              keyboardType: this._changeKeyboardType(currentHeading),
              decoration: new InputDecoration(
                prefixIcon: currentIcon,
                labelText: currentHeading,
                border: OutlineInputBorder(),
              ),
            )
        );
      }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      autovalidate: true,
      child: Expanded(
        child: (this.createListItems())
      )
    );
  }
}

主要出问题的是这一行代码:keyboardType: this._changeKeyboardType(currentHeading) ... 我是否走错了方向?任何方向都会非常有帮助。我基本上想让描述的textFormField成为多行文本,以便用户可以更好地可视化他们的描述。


同样的问题,我也没有找到解决方案 :( - rickdroio
为了解决这个问题,我还添加了 maxLines 属性,以允许它超过一行。当我需要多行输入时,我将其设置为 null,而当我需要单行输入时,我将其设置为 1。 - awaisbair
请查看此链接 https://dev59.com/NLP3oIgBc1ULPQZFcXF6#71152144,可能会有用。 - lava
2个回答

6

我目前的工作解决方案:

// Where entry is an object containing its focusNode and textInputType
entry.focusNode.unfocus();
setState(() {
  entry.textInputType = type;
});
// The delay was necessary, otherwise only the 2nd tap would actually change
Future.delayed(const Duration(milliseconds: 1), () {
  FocusScope.of(context).requestFocus(entry.focusNode);
});

目前唯一的缺点是键盘在使用新的TextInputType之前会消失,但我还无法解决这个问题。

谷歌的电子表格应用可以在不关闭键盘的情况下实现即时变化,如果能知道如何在Flutter中实现就太好了。

你需要更改你的逻辑,因为我的示例是异步的。
如果有帮助,请告诉我或者如果您需要更多帮助。
或者,如果您已经解决了问题,也请告诉我如何解决。

可能喜欢这样: enter image description here

致谢:它受到https://stackoverflow.com/a/58498474/3484824的启发。


请提供“entry”的声明,它是TextFormField的控制器还是关键属性? - Ameena Shafeer
1
哦,是的,我现在正在用手机,但本质上它是一个Dart类,具有属性focusNodetextInputType,希望这可以帮到你? - Can Rau
1
WidgetsBinding.instance.addPostFrameCallback((_) => textFieldFocusNode.requestFocus(),);Future.delayed()更合适。 - Hrishikesh Kadam

0
我的解决方案是受Can Rau启发,使用RadioListTile。当用户选择一个tile时,它会更改搜索字段的输入。首先为键盘类型定义一个变量:

TextInputType keyboard = TextInputType.text;

在RadioListTile的Onchange事件中,选择您需要的任何类型,例如数字:
RadioListTile( ...
onChanged: ((value) {keyboard = TextInputType.number;                                
setState(() {_textformfieldFocus.requestFocus();});                                
_textformfieldFocus.unfocus();                                
Future.delayed(const Duration(milliseconds: 10),() {                                  
FocusScope.of(context).requestFocus(_textformfieldFocus);                                
});}),

在TextFormField中:

TextFormField( ...
keyboardType : keyboard,

这个没有延迟,也不会显示两个键盘


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