Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the semantics of each InputType constant?

You can set a TextView's inputType to one of the values from InputType to hint that the typed-in text should be a person's name, phone number, &c. Even if the input method doesn't respect this hint, the TextView uses a KeyListener and/or TransformationMethod to ensure that only relevant characters can be entered, or to have effects like masking the password. Even the flags are more than just hints: they can change the behaviour of the TextView significantly (the most obvious example being EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE).

Google's documentation is very vague about the actual effect of each inputType. What characters are actually permitted in each case? How does this vary by locale, if at all? Even if there is no documented answer, and it's liable to change between versions, I'd still like to know the expected behaviour.

like image 910
Dan Hulme Avatar asked Oct 14 '13 22:10

Dan Hulme


1 Answers

You can find this out by inspecting the source of the *KeyListener classes, though of course this may be changed in different versions or by manufacturer or carrier customizations. The below is based on the AOSP 4.3 source. These are only the effects that each type has on Android itself: input methods also use the types as hints to better predict what the user is likely to type. For example, although TYPE_TEXT_VARIATION_PERSON_NAME only has the effect of disabling spell-check, the IM might respond to this type by auto-completing from a dictionary of common names instead of from a language dictionary.

To experiment with input types and IME options, I hacked up a quick app that lets you select them from a list in a GUI, so you don't have to edit an XML layout and rebuild an app to do it. If you want to find out more, or check how they interact with a given IM app, download IM prove free from Google Play.

TYPE_NULL

This one is actually documented:

This should be interpreted to mean that the target input connection is not rich, it can not process and show things like candidate text nor retrieve the current text, so the input method will need to run in a limited "generate key events" mode, if it supports it. Note that some input methods may not support it, for example a voice-based input method will likely not be able to generate key events even if this flag is set.

This makes it sounds like it's for cases where you're not editing text, but pressing a key on the IM will do some action directly. But in fact it hides the IM completely. From the app's point of view, you almost never want this: set it if you only want a hardware keyboard to be able to enter text.

From the IM's point of view, you'll get this type passed to onStartInput a lot, usually when Android is about to hide the IM because a different activity is coming to the foreground. You want responding to this input type to be fast. There could be two reasons why it works this way, but someone involved with the design would have to confirm why:-

  1. It could be to let the IM know that editing is completely finished in that window (unlike onFinishInput, which merely means the IM is being hidden), so it can free memory used for dictionaries and the like until editing restarts.

  2. It could be part of what allows a hardware keyboard to use arrow keys for scrolling, menu accelerator keys, and so on, even when no text input is taking place.

Classes

Numeric types

TYPE_CLASS_NUMBER gives you the digits 0-9. In addition, adding TYPE_NUMBER_FLAG_SIGNED lets you have + or -, but only as the first character. Adding TYPE_NUMBER_FLAG_DECIMAL lets you have . in any position, but only once. You can have both signed and decimal. As far as I can tell, this isn't localized, so the allowed characters are the same even for locales where . is the thousands separator and , is the decimal point, or for locales with different number characters.

TYPE_CLASS_PHONE lets you have the digits 0-9, as well as any of #*+-(),/N.; and space. You can have those characters in any order and any number of times: there's no formatting check.

TYPE_CLASS_DATETIME | TYPE_DATETIME_VARIATION_DATE lets you have the digits 0-9 as well as any of /-.. Again, there's no extra check for formatting, so you can have them in any order.

TYPE_CLASS_DATETIME | TYPE_DATETIME_VARIATION_TIME lets you have the digits 0-9 as well as : and any of amp (for writing "am" or "pm", but you can use them in any order and position). Slightly perversely, you can't have space or . for "3 pm" or "2 p.m." or even "2.30". Again, it doesn't seem to be localized.

TYPE_CLASS_DATETIME | TYPE_DATETIME_VARIATION_NORMAL gets you 0-9 as well as :/-, space, and amp. This notably doesn't include . even though it's allowed in a date.

Based on the above observations, I can't say I'd recommend using any of the above classes. They all seem to have major absences and prevent localization. The above are the only classes with character restrictions.

TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_PASSWORD does as you'd expect: it uses a TransformationMethod to obscure the typed characters.

Text types

In TYPE_CLASS_TEXT, setting TYPE_TEXT_VARIATION_EMAIL_ADDRESS or TYPE_TEXT_VARIATION_EMAIL_SUBJECT makes a press of the enter key move focus to the next field instead of inserting a newline.

TYPE_TEXT_VARIATION_FILTER will prevent the input method going to full-screen (extract) mode.

TYPE_TEXT_VARIATION_PASSWORD has the obvious effect: it uses a TransformationMethod to obscure the typed characters. TYPE_TEXT_VARIATION_VISIBLE_PASSWORD still uses the TransformationMethod to prevent the text being copied

All of the following text variations allow spell-checking if TYPE_TEXT_FLAG_NO_SUGGESTIONS is not set. That is, using an class that is not TYPE_CLASS_TEXT or a variation that is not in this list has the same effect as setting TYPE_TEXT_FLAG_NO_SUGGESTIONS (which is described later).

  • TYPE_TEXT_VARIATION_NORMAL
  • TYPE_TEXT_VARIATION_EMAIL_SUBJECT
  • TYPE_TEXT_VARIATION_LONG_MESSAGE
  • TYPE_TEXT_VARIATION_SHORT_MESSAGE
  • TYPE_TEXT_VARIATION_WEB_EDIT_TEXT

Flags

The presence or absence of InputType.TYPE_TEXT_FLAG_MULTI_LINE has non-obvious side-effects. If the type class is not TYPE_CLASS_TEXT, it is always as if the flag were not set, and the TextView goes into single-line mode. Setting lines or maxLines to 1 only affects the way the text is displayed: it does not start single-line mode.

In single-line mode:-

  • the ellipsize option defaults to end
  • pressing enter performs the "editor action" or moves focus to the next field (just as for email addresses or subjects, above); otherwise, it inserts a newline
  • pressing tab moves focus to the next field, only if TYPE_TEXT_FLAG_IME_MULTI_LINE is not set; otherwise it inserts a tab character
  • the imeOptions can include an "editor action" to replace the enter key on a soft keyboard; in multi-line mode, TextView will add IME_FLAG_NO_ENTER_ACTION to the imeOptions
  • maxLines is automatically set to 1
  • adding a newline to the field (e.g. using setText) has no effect, and a carriage return is replaced with a zero-width space (U+FEFF)

TYPE_TEXT_FLAG_CAP_* use TextUtils.getCapsMode to decide whether to capitalize each character. The rules are a little baroque and are not locale-sensitive. AFAICT, this only takes effect if the corresponding setting is enabled in the default keyboard.

When TYPE_TEXT_FLAG_AUTO_CORRECT is set, space, tab, newline, any Unicode "end punctuation" character, or any of ,.!?" will trigger auto-correction of the preceding word (in this context, that's the longest sequence of Unicode letters and apostrophes). If the whole word doesn't have a correction, it continues to retry with shorter subsequences. The corrections come from a fixed system resource com.android.internal.R.xml.autotext and are separate from any configured spell-checker.

TYPE_TEXT_FLAG_NO_SUGGESTIONS (or the text variations listed earlier) stops the text being spell-checked. This prevents the spell-check suggestions list being shown, and also stops misspelled words being highlighted. The input method can still provide completions if it chooses.

Other oddities

Long-tapping a TextView usually selects the tapped word, but if the input type is one of the following, it selects all of the text instead:-

  • TYPE_CLASS_NUMBER
  • TYPE_CLASS_PHONE
  • TYPE_CLASS_DATETIME (any variation)
  • TYPE_TEXT_VARIATION_URI
  • TYPE_TEXT_VARIATION_EMAIL_ADDRESS
  • TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS
  • TYPE_TEXT_VARIATION_FILTER
like image 154
Dan Hulme Avatar answered Sep 20 '22 19:09

Dan Hulme