active_keyboard_language 0.0.1 copy "active_keyboard_language: ^0.0.1" to clipboard
active_keyboard_language: ^0.0.1 copied to clipboard

Detects and streams the active keyboard (IME) language on iOS and Android, with an RTL-aware Directionality helper widget.

active_keyboard_language #

Detects the active keyboard (IME) language on iOS and Android, streams changes in real time, and provides an RTL-aware Directionality helper widget.

Typing in Assamese, switching the keyboard language via the globe key, and the field flipping instantly to Arabic

Solves flutter/flutter#25841 ("Add a way to detect keyboard language") — open since December 2018.

Features #

  • getCurrentLanguage() — BCP-47 tag of the active keyboard language (e.g. en-US, ar, hi)
  • onLanguageChanged — broadcast stream that fires when the user switches keyboard language (globe key)
  • isRtl() — convenience check derived from a language tag
  • KeyboardAwareDirectionality — widget that wraps a child and flips TextDirection automatically
  • Android (API 21+) and iOS (13+)
  • Graceful degradation: returns null / an empty stream on unsupported platforms instead of throwing

Usage #

import 'package:active_keyboard_language/active_keyboard_language.dart';

final language = await KeyboardLanguage.getCurrentLanguage(); // e.g. "ar"

KeyboardLanguage.onLanguageChanged.listen((language) {
  print('keyboard language changed to $language');
});

KeyboardLanguage.isRtl('ar'); // true

Wrap any widget that should flip direction with the keyboard:

KeyboardAwareDirectionality(
  child: TextField(),
)

If the child is a text field, pass its TextEditingController too so the field clears itself on every language switch (see the Android caveat below for why that matters):

final controller = TextEditingController();

KeyboardAwareDirectionality(
  controller: controller,
  child: TextField(controller: controller),
)

API #

Member Type Description
KeyboardLanguage.getCurrentLanguage() Future<String?> BCP-47 tag of the active keyboard language, or null if undetectable.
KeyboardLanguage.onLanguageChanged Stream<String?> Emits the new tag whenever the active keyboard language changes. Broadcast; debounced ~100ms.
KeyboardLanguage.isRtl(tag) bool True if tag's primary language subtag is a right-to-left script language.
KeyboardAwareDirectionality Widget Wraps child in a Directionality that follows the active keyboard language.
KeyboardAwareDirectionality.controller TextEditingController? Optional. If provided, its text is cleared on every language change (not the initial seed) — see the Android caveat below.
KeyboardAwareDirectionality.onLanguageChanged ValueChanged<String?>? Optional callback fired with the normalized tag on every change.

Language coverage #

getCurrentLanguage()/onLanguageChanged pass through whatever tag the OS reports — there's no closed list, so any keyboard language iOS or Android ships is supported for detection, including third-party keyboards (Gboard, SwiftKey, Sogou, etc.) as long as they report a subtype/input mode.

isRtl() does use a fixed list, since RTL-ness isn't derivable from the tag alone: ar, he, fa, ur, ps, sd, ckb (Sorani Kurdish), dv, yi, ug (Uyghur). This matches every RTL-script keyboard both platforms actually ship system-level support for. Plain ku (Kurmanji Kurdish) is deliberately excluded — its default keyboard is Latin-script and therefore LTR.

Normalization also remaps a handful of legacy Java/Android ISO-639 codes (iwhe, jiyi, inid) that can surface from the deprecated InputMethodSubtype.locale API path on Android API 21–23, so isRtl() and tag comparisons stay correct on older devices too.

Platform notes #

  • No special permissions are required on either platform.
  • Android: detection reflects the IME's currently selected subtype. Gboard's "multilingual typing" mode reports one subtype while accepting several languages — the reported tag is whichever subtype is selected, not every language the keyboard is currently able to type. Some OEM keyboards (Sogou, iFlytek, etc.) report unusual locale strings; these are normalized defensively and fall back to null rather than crash.
  • Android caret reset: switching the keyboard's language subtype forces Android to restart the focused field's input connection, which can reset the caret to the start of the text. If a field already has mixed-script content, characters typed after the switch can land in the wrong place — this is a platform behavior, not something this package's code touches. Pass a controller to KeyboardAwareDirectionality (see Usage) to clear the field on every switch and sidestep it entirely.
  • iOS: primaryLanguage can report the pseudo-languages "emoji" or "dictation" when those keyboards are active — this package passes through the last known real language in that case instead of surfacing the pseudo-language.
  • iOS initial read before any field is focused: before the first text field in your app ever gains focus, there is no first responder to read a language from, so the initial value falls back to UITextInputMode.activeInputModes.first — the order of your enabled keyboards in Settings, not necessarily the one you last typed with. This self-corrects as soon as a keyboard actually appears (onLanguageChanged fires once a real field is focused, even if iOS doesn't consider the system-wide input mode to have "changed").

Roadmap (v2) #

  • Programmatically changing/forcing the keyboard language (flutter/flutter#99606).
  • Listing all installed keyboard languages.
  • Per-TextField language preference.
0
likes
160
points
0
downloads

Documentation

API reference

Publisher

verified publishercordeliaapps.com

Weekly Downloads

Detects and streams the active keyboard (IME) language on iOS and Android, with an RTL-aware Directionality helper widget.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on active_keyboard_language

Packages that implement active_keyboard_language