Small details that build taste in Flutter.

curated by Kamran BekirovKamran Bekirov

Give the keyboard action button a job

Every text field puts an action key on the keyboard. The default is "done", and it just closes the keyboard.

It can drive the whole form instead: every field focuses to the next one, and the last one submits the form:

Use textInputAction to customize the behavior:

TextFormField(
  // Keyboard key: "next"
  textInputAction: TextInputAction.next,
),
TextFormField(
  textInputAction: TextInputAction.next,
),
TextFormField(
  // Keyboard key: "done"
  textInputAction: TextInputAction.done,
  onFieldSubmitted: (_) => _submit(),
),

With next, Flutter moves focus to the next field on its own. No need for a custom FocusNode.

onFieldSubmitted runs when the user presses the action key, so give it the same method the submit button calls.

done is the neutral pick. When the form has one clear action, match the key to it: TextInputAction.send for a message, go for navigation, search for a query. The behavior is the same, but the keyboard now says what the key does.

That's almost the whole list. The rest are platform-bound: Android also has previous (jump back a field) and none (no action), iOS has join, route, continueAction, and emergencyCall. Using one on the wrong platform throws exception ONLY in debug mode.

One thing not to break: providing onEditingComplete replaces this default behavior, so the next focus and the keyboard close become your job.

Multiline fields are the other direction: there the return key must go down a line, not submit. Set maxLines above 1 and leave the rest alone: the keyboard type defaults to KeyboardType.multiline and the action to TextInputAction.newline, so the key inserts a line break. That's what users will expect in multiline text fields (comments, messages etc.)

Kamran Bekirov
Kamran Bekirov

Want this level of care in your Flutter apps?

Work With Me