Какова семантика каждой константы InputType?

Вы можете установить inputType TextView в одно из значений из InputType, чтобы указать, что вводимый текст должен быть именем человека, номером телефона и т. д. Даже если метод ввода не учитывает эту подсказку, TextView использует KeyListener и/или TransformationMethod, чтобы гарантировать, что можно вводить только соответствующие символы, или для таких эффектов, как маскировка пароля. Даже флаги — это больше, чем просто подсказки: они могут значительно изменить поведение TextView (самый очевидный пример — EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE).

Документация Google очень расплывчата в отношении фактического эффекта каждого inputType. Какие символы действительно разрешены в каждом случае? Как это зависит от региона, если вообще? Даже если нет задокументированного ответа и он может меняться между версиями, мне все равно хотелось бы знать ожидаемое поведение.


person Dan Hulme    schedule 14.10.2013    source источник


Ответы (1)


Вы можете узнать это, проверив источник классов *KeyListener, хотя, конечно, это может быть изменено в разных версиях или в настройках производителя или оператора связи. Приведенное ниже основано на исходном коде AOSP 4.3. Это только эффекты, которые каждый тип оказывает на сам Android: методы ввода также используют типы в качестве подсказок, чтобы лучше предсказать, что пользователь может ввести. Например, хотя TYPE_TEXT_VARIATION_PERSON_NAME имеет эффект только отключения проверки орфографии, IM может реагировать на этот тип автозаполнением из словаря общих имен, а не из языкового словаря.

Чтобы поэкспериментировать с типами ввода и параметрами IME, я взломал быстрое приложение, которое позволяет вам выбирать их из списка в графическом интерфейсе, поэтому вам не нужно редактировать XML-макет и перестраивать приложение для этого. Если вы хотите узнать больше или проверить, как они взаимодействуют с данным приложением для обмена мгновенными сообщениями, загрузите IM Prove бесплатно из Google Play.

TYPE_NULL

Это действительно задокументировано:

Это следует интерпретировать как означающее, что целевое входное соединение не является богатым, оно не может обрабатывать и отображать такие вещи, как текст-кандидат, или извлекать текущий текст, поэтому метод ввода должен будет работать в ограниченном режиме «генерировать ключевые события», если он поддерживает это. Обратите внимание, что некоторые методы ввода могут не поддерживать его, например, метод голосового ввода, скорее всего, не сможет генерировать ключевые события, даже если этот флаг установлен.

Это звучит так, как будто это для случаев, когда вы не редактируете текст, но нажатие клавиши в IM напрямую выполняет какое-то действие. Но на самом деле он полностью скрывает ИМ. С точки зрения приложения, вам это почти никогда не нужно: установите его, если вы хотите, чтобы аппаратная клавиатура могла только вводить текст.

С точки зрения IM, вы будете часто передавать этот тип в onStartInput, обычно когда Android собирается скрыть IM, потому что на передний план выходит другая активность. Вы хотите, чтобы ответ на этот тип ввода был быстрым. Может быть две причины, почему это работает таким образом, но кто-то, кто занимается дизайном, должен подтвердить, почему:

  1. Это может быть сообщение IM, что редактирование полностью завершено в этом окне (в отличие от onFinishInput, которое просто означает, что IM скрыто), поэтому он может освободить память, используемую для словарей и тому подобного, до перезапуска редактирования.

  2. Это может быть частью того, что позволяет аппаратной клавиатуре использовать клавиши со стрелками для прокрутки, клавиши быстрого доступа к меню и т. д., даже когда не происходит ввода текста.

Классы

Числовые типы

TYPE_CLASS_NUMBER дает вам цифры 0-9. Кроме того, добавление TYPE_NUMBER_FLAG_SIGNED позволяет использовать + или -, но только в качестве первого символа. Добавление TYPE_NUMBER_FLAG_DECIMAL позволяет вам иметь . в любой позиции, но только один раз. Вы можете использовать как знаковые, так и десятичные числа. Насколько я могу судить, это не локализовано, поэтому разрешенные символы одинаковы даже для локалей, где . – разделитель тысяч, а , – десятичная точка, или для локалей с разными числовыми символами. .

TYPE_CLASS_PHONE позволяет использовать цифры от 0 до 9, а также любые из #*+-(),/N.; и пробелов. Вы можете использовать эти символы в любом порядке и любое количество раз: нет проверки форматирования.

TYPE_CLASS_DATETIME | TYPE_DATETIME_VARIATION_DATE позволяет вам иметь цифры 0-9, а также любые из /-.. Опять же, нет дополнительной проверки форматирования, так что вы можете иметь их в любом порядке.

TYPE_CLASS_DATETIME | TYPE_DATETIME_VARIATION_TIME позволяет вам использовать цифры 0-9, а также : и любую из amp (для написания «am» или «pm», но вы можете использовать их в любом порядке и в любом положении). Немного извращенно, у вас не может быть места или . для "15:00" или "14:00" или даже "2.30". Опять же, похоже, что это не локализовано.

TYPE_CLASS_DATETIME | TYPE_DATETIME_VARIATION_NORMAL дает вам 0-9, а также :/-, пробел и amp. В частности, это не включает ., хотя это разрешено в дате.

Основываясь на приведенных выше наблюдениях, я не могу сказать, что рекомендую использовать какой-либо из вышеперечисленных классов. Все они, кажется, имеют серьезные недостатки и мешают локализации. Выше приведены единственные классы с ограничениями по символам.

TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_PASSWORD делает то, что вы ожидаете: он использует TransformationMethod, чтобы скрыть введенные символы.

Типы текста

В TYPE_CLASS_TEXT установка TYPE_TEXT_VARIATION_EMAIL_ADDRESS или TYPE_TEXT_VARIATION_EMAIL_SUBJECT приводит к тому, что нажатие клавиши ввода перемещает фокус на следующее поле вместо вставки новой строки.

TYPE_TEXT_VARIATION_FILTER предотвратит переход метода ввода в полноэкранный (извлечение) режим.

TYPE_TEXT_VARIATION_PASSWORD имеет очевидный эффект: он использует TransformationMethod, чтобы скрыть вводимые символы. TYPE_TEXT_VARIATION_VISIBLE_PASSWORD по-прежнему использует TransformationMethod для предотвращения копирования текста

Все следующие варианты текста допускают проверку орфографии, если TYPE_TEXT_FLAG_NO_SUGGESTIONS не установлено. То есть использование класса, отличного от TYPE_CLASS_TEXT, или варианта, отсутствующего в этом списке, имеет тот же эффект, что и установка TYPE_TEXT_FLAG_NO_SUGGESTIONS (описанная ниже).

  • 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

Флаги

Наличие или отсутствие InputType.TYPE_TEXT_FLAG_MULTI_LINE имеет неочевидные побочные эффекты. Если класс типа не TYPE_CLASS_TEXT, всегда так, как если бы флаг не был установлен, и TextView переходит в однострочный режим. Установка lines или maxLines в 1 влияет только на способ отображения текста: он не запускает однострочный режим.

В однострочном режиме: -

  • опция размера эллипса по умолчанию заканчивается
  • нажатие ввода выполняет «действие редактора» или перемещает фокус на следующее поле (так же, как для адресов электронной почты или тем, описанных выше); в противном случае он вставляет новую строку
  • нажатие табуляции перемещает фокус на следующее поле, только если TYPE_TEXT_FLAG_IME_MULTI_LINE не установлено; в противном случае он вставляет символ табуляции
  • imeOptions может включать в себя «действие редактора» для замены клавиши ввода на программной клавиатуре; в многострочном режиме TextView добавит IME_FLAG_NO_ENTER_ACTION к imeOptions
  • maxLines автоматически устанавливается на 1
  • добавление новой строки в поле (например, с использованием setText) не имеет никакого эффекта, а возврат каретки заменяется пробелом нулевой ширины (U+FEFF)

TYPE_TEXT_FLAG_CAP_* используйте TextUtils.getCapsMode, чтобы решить, следует ли использовать заглавные буквы для каждого символа. Правила немного причудливы и не зависят от региональных настроек. AFAICT, это вступает в силу только в том случае, если соответствующий параметр включен на клавиатуре по умолчанию.

Когда установлено TYPE_TEXT_FLAG_AUTO_CORRECT, пробел, табуляция, новая строка, любой символ «конец пунктуации» Unicode или любой из ,.!?" вызовет автокоррекцию предыдущего слова (в данном контексте это самая длинная последовательность букв и апострофов Unicode). Если целое слово не имеет исправления, оно продолжает повторяться с более короткими подпоследовательностями. Исправления поступают из фиксированного системного ресурса com.android.internal.R.xml.autotext и отделены от любой настроенной проверки орфографии.

TYPE_TEXT_FLAG_NO_SUGGESTIONS (или варианты текста, перечисленные ранее) останавливает проверку правописания текста. Это предотвращает отображение списка вариантов проверки орфографии, а также останавливает выделение слов с ошибками. Метод ввода по-прежнему может обеспечивать завершение, если он выбирает.

Другие странности

Длительное нажатие на TextView обычно выбирает нажатое слово, но если тип ввода является одним из следующих, вместо этого выделяется весь текст: -

  • TYPE_CLASS_NUMBER
  • TYPE_CLASS_PHONE
  • TYPE_CLASS_DATETIME (любой вариант)
  • TYPE_TEXT_VARIATION_URI
  • TYPE_TEXT_VARIATION_EMAIL_ADDRESS
  • TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS
  • TYPE_TEXT_VARIATION_FILTER
person Dan Hulme    schedule 16.10.2013
comment
Обратите внимание, что в документах говорится, что KeyListener в основном используется только для жестких клавиатур. Таким образом, этот список может быть неточным для большинства пользователей. "Key presses on soft input methods are not required to trigger the methods in this listener, and are in fact discouraged to do so. The default android keyboard will not trigger these for any key to any application targeting Jelly Bean or later, and will only deliver it for some key presses to applications targeting Ice Cream Sandwich or earlier." - person Geobits; 16.10.2013
comment
@Geobits Документы говорят об этом. Но если вы сделаете тривиальное приложение для API 18, установите inputType соответствующим образом для EditText и запустите его с методом ввода по вашему выбору (включая метод по умолчанию), поведение будет точно таким же, как если бы KeyListener соответствующего типа фильтровал данные. нажатия клавиш. Я думаю, что документ говорит только о том, что метод ввода не должен проходить через KeyListener, потому что они запускаются в другом месте в TextView или InputMethodManager. - person Dan Hulme; 17.10.2013
comment
Я не сказал, что это неправильно, я просто указываю, что, поскольку это два отдельных варианта использования, один может измениться, не затрагивая другой, поэтому стоит перепроверить. Что касается блока кода, я согласен, что он не оптимален, но блочное цитирование в комментариях не работает, а огромный абзац, выделенный курсивом/жирным шрифтом, труднее читать (IMO). Это самый простой способ отделить цитату от моего комментария с первого взгляда. Если вы уверены в этом, не стесняйтесь добавить свое мнение здесь. Ирония в том, что вы решили использовать форматирование кода, чтобы отчитать меня за это. - person Geobits; 17.10.2013
comment
Так что же делают TYPE_NULL, TYPE_TEXT_VARIATION_NORMAL и TYPE_TEXT_VARIATION_WEB_EDIT_TEXT? И чем они отличаются? - person Fred; 02.03.2014
comment
Я добавил некоторую информацию о TYPE_NULL в свой ответ. Все, что я знаю об этих двух других типах, уже есть. NORMAL используется по умолчанию и заставляет IM вести себя нормально; WEB_EDIT_TEXT предназначен для установки веб-браузером в формах веб-ввода, но AFAICT не имеет особого эффекта в самом Android. Экспериментируя, я вижу, что SwiftKey действует так, как если бы было установлено TYPE_TEXT_FLAG_CAP_SENTENCES, если тип WEB_EDIT_TEXT, а Google Keyboard — нет. - person Dan Hulme; 02.03.2014