Skip to main content

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 (iw→he, ji→yi, in→id) 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
181
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