Многострочный EditText с меткой действия Done SoftInput 2.3

Есть ли способ иметь Multi-Line EditText представить и использовать ярлык действия IME "Готово" на Android 2.3?

В Android 2.2 это не проблема, кнопка ввода показывает ярлык действия IME "Готово" (android:imeActionLabel="actionDone") и отклоняет Soft Input при нажатии.

При настройке EditText для многострочного Android 2.3 убирает возможность показывать действие "Готово" для клавиатуры программного ввода.

Мне удалось изменить поведение кнопки ввода Soft Input с помощью KeyListener, однако кнопка ввода по-прежнему выглядит как клавиша ввода.


Вот декларация EditText

<EditText
        android:id="@+id/Comment"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="0dp"
        android:lines="3"
        android:maxLines="3"
        android:minLines="3"
        android:maxLength="60"
        android:scrollHorizontally="false"
        android:hint="hint"
        android:gravity="top|left"
        android:textColor="#888"
        android:textSize="14dp"
        />
<!-- android:inputType="text" will kill the multiline on 2.3! -->
<!-- android:imeOptions="actionDone" switches to a "t9" like soft input -->

Когда я проверяю inputType значение после загрузки, устанавливающее представление содержимого в действии, отображается как:

inputType = 0x20001

Который:

  • класс = TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_NORMAL
  • флаги = InputType.TYPE_TEXT_FLAG_MULTI_LINE

7 ответов

Решение

Ну, после перечитывания TextView а также EditorInfo документы, стало ясно, что платформа собирается заставить IME_FLAG_NO_ENTER_ACTION для многострочных текстовых представлений.

Обратите внимание, что TextView автоматически установит этот флаг для вас при многострочном просмотре текста.

Мое решение состоит в том, чтобы подкласс EditText и настройте параметры IME после того, как платформа настроит их:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    InputConnection connection = super.onCreateInputConnection(outAttrs);
    int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
    if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
        // clear the existing action
        outAttrs.imeOptions ^= imeActions;
        // set the DONE action
        outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
    }
    if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
        outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
    }
    return connection;
}

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

Ответ Оххороба в основном правильный, но его код действительно очень избыточен! Это в основном эквивалентно этой гораздо более простой версии (полный код для ленивых читателей):

package com.example.views;

import android.content.Context;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;

// An EditText that lets you use actions ("Done", "Go", etc.) on multi-line edits.
public class ActionEditText extends EditText
{
    public ActionEditText(Context context)
    {
        super(context);
    }

    public ActionEditText(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public ActionEditText(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs)
    {
        InputConnection conn = super.onCreateInputConnection(outAttrs);
        outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        return conn;
    }
}

Обратите внимание, что некоторые inputType варианты, такие как textShortMessage заставить это не работать! Я предлагаю вам начать с inputType="text", Вот как вы можете использовать его в своем XML.

<com.example.views.ActionEditText
    android:id=...
    android:layout_stuff=...
    android:imeOptions="actionDone"
    android:inputType="textAutoCorrect|textCapSentences|textMultiLine"
    android:maxLines="3" />

Альтернативное решение для создания подкласса класса EditText состоит в том, чтобы настроить ваш экземпляр EditText следующим образом:

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

По крайней мере, это работает для меня на Android 4.0. Он настраивает экземпляр EditText так, чтобы пользователь редактировал однострочную строку, которая отображается с мягким переносом на несколько строк, даже если установлено действие IME.

После предыдущего ответа

public class MultiLineText extends EditText {

    public MultiLineText(Context context) {
        super(context);
    }

    public MultiLineText(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public MultiLineText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnection connection = super.onCreateInputConnection(outAttrs);
        int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
        if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
            // clear the existing action
            outAttrs.imeOptions ^= imeActions;
            // set the DONE action
            outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
        }
        if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
            outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        }
        return connection;
    }
}

Используйте это как

<myapp.commun.MultiLineText
  android:id="@+id/textNotes"
  android:layout_height="wrap_content"
  android:minHeight="100dp"
  android:layout_width="wrap_content"
  android:hint="Notes"
  android:textSize="20sp"
  android:padding="7dp"
  android:maxLines="4"/> 

Для выполнения действия Готово вы можете использовать:

XML

android:inputType="text|textCapSentences"    

ДЖАВА

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

Я надеюсь, что его работа для вас.

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

У меня та же проблема, и мое очевидное решение было просто добавить кнопку "Готово" и позволить кнопке ввода добавить новые строки.

Используйте эти атрибуты в своем XML.

андроид:inputType="textImeMultiLine"

андроид:imeOptions="actionDone"

Другие вопросы по тегам