awaisbair
awaisbair

Reputation: 83

[Flutter/Dart]: How to dynamically change the keyboard type for a TextFormField in a Form?

I have a Widget that renders a ListView of TextFormFields to input data. However, I want to change the keyboard type for one of my textfields dynamically. Here is an overview of the Widget:


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

The main line that isn't working is: keyboardType: this._changeKeyboardType(currentHeading) ... Am I approaching this problem the wrong way? Any direction will be super helpful. I basically want the textFormFeld for the description being multiline so users can have a better visualization of their description.

Upvotes: 8

Views: 6551

Answers (2)

Acodi Systems
Acodi Systems

Reputation: 1

My solution, inspired in Can Rau using RadioListTile, when user choose one tile, it changes the input of a search field. first define a variable for the keyboard type :

TextInputType keyboard = TextInputType.text;

in the Onchange off the RadioListTile choose whatever type you need, for example number:

RadioListTile( ...
onChanged: ((value) {keyboard = TextInputType.number;                                
setState(() {_textformfieldFocus.requestFocus();});                                
_textformfieldFocus.unfocus();                                
Future.delayed(const Duration(milliseconds: 10),() {                                  
FocusScope.of(context).requestFocus(_textformfieldFocus);                                
});}),

And in the TextFormField :

TextFormField( ...
keyboardType : keyboard,

This has no delay and doesn´t shows 2 keyboards

Upvotes: 0

Can Rau
Can Rau

Reputation: 3819

My working solution for now:

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

Only downside I couldn't fix so far is that the keyboard is disappearing before it re-appears with the new TextInputType.

Google's Spreadsheet app does it instantaneous without the close, would love to know if and how that'll be doable in Flutter.

You'd have to change your logic as my example is asynchronous.
Let me know if that helps or if you need more help.
Or, if you've already figured it out, how you did it

May like this: enter image description here

Credits: It's inspired by https://stackoverflow.com/a/58498474/3484824

Upvotes: 7

Related Questions