Mobile Development 16 min read

Understanding Flutter Keyboard Invocation Process and Solutions to Common Issues

This article explains the Flutter soft‑keyboard invocation flow on Android and iOS, analyzes page‑repaint and animation problems such as stutter on specific devices, and presents practical fixes including performance flags, MediaQuery handling, and native input adjustments.

ByteDance Dali Intelligent Technology Team
ByteDance Dali Intelligent Technology Team
ByteDance Dali Intelligent Technology Team
Understanding Flutter Keyboard Invocation Process and Solutions to Common Issues

Background

When developing with Flutter, developers often encounter keyboard‑related problems. This article describes the soft‑keyboard invocation process, how the page moves and animates, and provides solutions to several known issues.

Flutter Keyboard Flow and Principles

On Android, tapping a TextField triggers TextInputPlugin to call the system InputMethodManager.showSoftInput . On iOS, the FlutterTextInputView implements the UITextInput protocol and calls becomeFirstResponder to show the keyboard.

The keyboard appearance causes the FlutterView to shift upward, driven by a system‑triggered animation. Two key points are:

The keyboard animation is system‑controlled and not managed by Flutter.

The page shift updates the WindowInsets property, which changes Metrics and forces a frame redraw.

Page Repaint Logic After Keyboard Invocation

The process can be simplified into three steps:

The keyboard occupies space in FlutterView , changing its WindowInsets .

The WindowInsets change updates Metrics and propagates from the Platform thread to the UI thread.

scheduleForceFrame is called to force a new frame.

To smooth the animation, an AnimatedContainer can be wrapped around the widget tree, adjusting its padding based on window.viewInsets.bottom / window.devicePixelRatio .

Known Keyboard Issues and Solutions

3.1 Keyboard Animation Stutter

On some devices (e.g., Samsung S10) the keyboard animation causes severe frame‑by‑frame rebuilds. Using Systrace, it was observed that the device triggers multiple WindowInsets changes (0 → 10 → 40 → … → 400) instead of a single change. The solution includes:

Calling Performance.setCurrentIsKeyboardScene(true) to suppress MediaQuery updates for 300 ms during keyboard show/hide.

Detecting rapid consecutive Metrics changes (within 32 ms) and replacing AnimatedContainer with a simple Padding widget.

Resulting Systrace graphs show a single WindowInsets change and smoother animation.

3.2 Keyboard Not Hiding After Lock Screen

The issue occurs when the device locks while the keyboard is visible; after unlocking, the keyboard remains shown. The root cause is that TextInputMethodHandler becomes null during onPause , preventing the hide call. The fix records whether the keyboard was ever shown and forces a hide when the handler is cleared.

public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
  if (textInputMethodHandler == null) {
    return;
  }
  switch (method) {
    case "TextInput.hide":
      textInputMethodHandler.hide();
      isKeyBoardShow = false;
      result.success(null);
      break;
    ...
  }
}

3.3 iOS Sogou Input Method Long‑Press Send Not Adding Newline

Long‑pressing the send button inserts a carriage‑return (ASCII 13) instead of a line‑feed (ASCII 10). By inspecting the character codes in onChanged , the problem was identified and fixed by replacing the character in EditableTextState.updateEditingValue or in the plugin.

TextField(
  keyboardType: TextInputType.multiline,
  maxLines: 5,
  minLines: 1,
  textInputAction: TextInputAction.send,
  onChanged: (value) { /* ... */ },
  onSubmitted: (_) { /* ... */ },
  decoration: const InputDecoration(
    hintText: '输入',
    filled: true,
    fillColor: Colors.white,
    contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
    isDense: true,
    border: OutlineInputBorder(
      gapPadding: 0,
      borderRadius: BorderRadius.all(Radius.circular(4)),
      borderSide: BorderSide(width: 1, style: BorderStyle.none),
    ),
  ),
),

Printing character codes:

for (int v in value.codeUnits) {
  print('char code is $v');
}

ASCII 13 corresponds to '\r' (carriage return) and 10 to '\n' (line feed).

3.4 iOS Cursor Animation Causing CPU Spike

The cursor animation in EditableTextState fades alpha over 250 ms, pauses 150 ms, then repeats, raising CPU usage from 4 % to 16 % on iPhone 12. Aligning the animation with Android’s instant visibility (alpha 0 → 1) reduces the load.

3.5 Cursor Remains After Keyboard Dismissal on iOS

Native iOS hides the cursor when the keyboard is dismissed, but Flutter keeps the blinking cursor. A listener on keyboard hide notifications now clears the cursor, matching native behavior.

3.6 iOS 12+ Long‑Press Space Cursor Lag on Non‑English Text

Long‑pressing the space bar for cursor movement becomes laggy with non‑Latin characters. Adding a UITextInteraction to FlutterTextInputView resolves the issue.

if (@available(iOS 13.0, *)) {
  UITextInteraction* interaction = [UITextInteraction textInteractionForMode:UITextInteractionModeEditable];
  interaction.textInput = self;
  [self addInteraction:interaction];
}

Google’s official fix is tracked in engine PR #26486.

Conclusion

Understanding the full keyboard invocation flow—how WindowInsets changes trigger Metrics updates and force frame redraws—helps diagnose and resolve performance and functional issues in Flutter. Tools like Systrace and Instruments are valuable for pinpointing the exact cause, and targeted fixes such as performance flags, MediaQuery handling, and native interaction adjustments can restore smooth user experiences.

flutterPerformanceiOSAndroidkeyboardMediaQueryWindowInsets
ByteDance Dali Intelligent Technology Team
Written by

ByteDance Dali Intelligent Technology Team

Technical practice sharing from the ByteDance Dali Intelligent Technology Team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.