Подтвердить что ты не робот

Поведение imeOptions, imeActionId и imeActionLabel

Я новичок в области разработки Android, и я пытаюсь понять, как настроить кнопки действия IME. Я просмотрел документацию Google, но я могу найти очень мало информации о ожидаемом поведении.

Из официального руководства Я понимаю, что кнопку действия клавиатуры можно настроить с помощью атрибутов:

  • android: imeOptions может установить текст/идентификатор кнопки, отображаемой рядом с клавишей пробела, на некоторые заранее определенные значения (например, actionGo установить метку ключа на Go и id на 2)
  • android: imeActionLabel установите метку кнопки, отображаемой внутри области ввода, когда клавиатура полноэкранная, обычно в альбомном режиме. Может быть установлено любое строковое значение.
  • android: imeActionId, как и предыдущий, но установите числовой идентификатор, переданный методу обратного вызова

Но после некоторых эмпирических попыток я обнаружил различное поведение между уровнями API 15 и следующими уровнями API.

Я создал простой элемент EditText со следующими атрибутами:

<EditText
        ...
        android:imeOptions="actionGo"
        android:imeActionLabel="Custom"
        android:imeActionId="666"
        android:inputType="text"/>

и я проверил эффект с различными уровнями API как в портретном, так и в ландшафтном режимах. Вот результат.

Уровень API 15 - 4.0.3

В портретном режиме метка ключа - Go, а идентификатор действия, переданный методу обратного вызова, равен 2, соответственно настройке imeOptions.

В ландшафтном режиме ключевой ярлык/идентификатор - Go/2 в качестве портретного режима, а кнопка, отображаемая в области ввода, - Custom/666, соответственно атрибутам imeActionLabel и imeActionId.

Уровень API 16, 17 и 18 - 4.1.2, 4.2.2 и 4.3

В портретном и ландшафтном режимах клавиша и кнопка отображаются с пользовательской меткой и привязаны к 666 id, игнорируя атрибут imeOptions.

Это несоответствие в поведении довольно раздражает, потому что:

  • с уровнем API >= 16 вы не можете различать кнопку кнопки и кнопки области ввода
  • с уровнем API = 15 вы не можете установить какой-либо пользовательский текст для ключевой кнопки.

Вы знаете, как получить это как в API 15, так и в 16+? Или, если есть способ получить согласованное поведение для всех (или, по крайней мере, части) версий API?

Может быть, мне что-то не хватает в настройках IME, которые могут оправдать различное поведение...

Большое спасибо!

4b9b3361

Ответ 1

Фактически это зависит от приложения метода ввода, а не от самой платформы Android, чтобы решить, что делать со значениями, которые вы установили.

Фреймворк Android просто передает значения, которые вы установили, на метод ввода, который затем может выбрать, какие кнопки будут отображаться на клавиатуре или "извлечен" EditText в полноэкранном режиме. Рамка Android влияет на EditorInfo двумя способами: -

  • Он передает его EditorInfo.makeCompatible, чтобы гарантировать, что значения в нем совместимы между клавиатурой и приложением targetApiVersion s. На данный момент это влияет только на некоторые значения InputType, а не на действие редактора, но это может измениться, если будут введены новые действия редактора (или совершенно новые настройки).

  • Он устанавливает поведение по умолчанию для метода ввода, в том числе поведение полноэкранных редакторов. Если метод ввода предпочитает не переопределять это поведение по умолчанию, то это может привести к поведению, которое отличается от версий Android. Многие клавиатуры предпочитают устанавливать свое поведение таким образом, чтобы оно соответствовало версиям Android.

По этой причине не так просто сказать, что определенное поле EditorInfo оказывает определенное влияние на любую данную версию, и нет способа обеспечить последовательное поведение даже на одной версии Android. Все, что вы делаете, - это подсказки для метода ввода, который выбирает, как представить их пользователю.

Ответ 2

Просто вызовите .setImeActionLabel() программно в java-кодах, чтобы установить ActionID (снова) на ваш желаемый.

editText.setImeActionLabel(getString(R.string.xxx), EditorInfo.IME_ACTION_GO);

Ответ 3

Если кто-то разрабатывает пользовательскую клавиатуру для Android и имеет проблему с меткой клавиши Enter, вы должны сделать следующее. В образце пользовательской клавиатуры Android у нас есть следующий метод в SoftKeyboard.java:

@Override
    public void onStartInput(EditorInfo attribute, boolean restarting)
    {
        super.onStartInput(attribute, restarting);
.
. // the implementation
. 
        mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
    }

Измените последнюю строку на следующую строку:

mCurKeyboard.setImeOptions(getResources(), attribute);

Теперь в LatinKeyboard.java измените метод setImeOptions, как показано ниже:

void setImeOptions(Resources res, EditorInfo ei)
    {
        if (mEnterKey == null)
        {
            return;
        }

        switch (ei.imeOptions & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION))
        {
            case EditorInfo.IME_ACTION_SEND:
                mEnterKey.iconPreview = null;
                mEnterKey.icon = null;
                mEnterKey.label = res.getText(R.string.label_send_key);
                break;
            case EditorInfo.IME_ACTION_GO:
                mEnterKey.iconPreview = null;
                mEnterKey.icon = null;
                mEnterKey.label = res.getText(R.string.label_go_key);
                break;
            case EditorInfo.IME_ACTION_NEXT:
                mEnterKey.iconPreview = null;
                mEnterKey.icon = null;
                mEnterKey.label = res.getText(R.string.label_next_key);
                break;
            case EditorInfo.IME_ACTION_SEARCH:
                mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search);
                mEnterKey.label = null;
                break;
            default:
                mEnterKey.iconPreview = null;
                mEnterKey.label = res.getText(R.string.label_enter_key);
                mEnterKey.icon = null;
                break;
        }

        if (ei.actionLabel != null)
        {
            mEnterKey.iconPreview = null;
            mEnterKey.icon = null;
            mEnterKey.label = ei.actionLabel;
        }
    }

Теперь ваша пользовательская клавиатура показывает соответствующую метку на основе того, что определено в xml файле для imeActionLabel.

Ответ 4

Когда вы начинаете новый проект Android, он дает хороший намек на ваш вопрос. Существует активность под названием LoginActivity, которую вы можете создать в качестве экрана входа по умолчанию. Эта операция создаст EditText так:

            <EditText
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/prompt_password"
                    android:imeActionId="@+id/login"
                    android:imeActionLabel="@string/action_sign_in_short"
                    android:imeOptions="actionUnspecified"
                    android:inputType="textPassword"
                    android:maxLines="1"
                    android:singleLine="true"/>

Теперь, если вы читаете документацию, вы должны знать, что атрибут imeOptions позволяет указать дополнительные действия для текстового поля. Например, клавиатура, которая появляется, имеет действие в нижнем правом углу, например "Далее". Используя imeOptions, вы можете выбрать другое действие из предопределенного списка, предоставленного Android. Вы можете указать что-то вроде "actionSend" или "actionSearch".

Как только вы сделаете это, чтобы выполнить Activity, вы можете прослушать это действие с помощью обработчика событий setOnEditorActionListener:

    mPasswordView = (EditText) findViewById(R.id.password);
    mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
            if (id == R.id.login || id == EditorInfo.IME_NULL) {
                attemptLogin();
                return true;
            }
            return false;
        }
    });

Обратите внимание, как мы ориентируемся на imeActionId здесь. Это еще один способ настроить таргетинг на EditText в вашей деятельности, а также иметь возможность изменять действие на вводе клавиатуры.