Багаторядковий EditText із міткою дії SoftInput Action на 2.3


82

Чи є спосіб EditTextприсутності багаторядкової лінії та використання мітки дій IME "Готово" на Android 2.3?

В Android 2.2 це не проблема, кнопка введення відображає ярлик дії IME "Готово" ( android:imeActionLabel="actionDone") і відхиляє програмне введення при натисканні.

Під час налаштування EditTextбагаторядкової версії Android 2.3 видаляє можливість показу дії "Готово" для клавіатури Soft Input.

Мені вдалося змінити поведінку кнопки м'якого введення за допомогою клавіші a 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

Відповіді:


163

Ну, перечитавши документи 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теж форсую , хоча цього можна досягти за допомогою нудної конфігурації макета.


24
Я зазвичай не даю загальних коментарів, таких як "omg дякую", але ця відповідь була достатньо корисною і недооціненою, що я вважав, що вона заслуговує визнання. Таким чином, omg дякую. :-)
орач

3
+1 для відповіді, але якщо ви встановлюєте тип введення тексту редагування з коду в цьому випадку. Він видаляє вертикальну прокрутку і додає горизонтальну прокрутку. Щоб вирішити цю проблему, використовуйте код нижче. editTextObj.setInputType (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE); Зазвичай це може статися, якщо ви повторно використовуєте подання, включаючи одне і те ж у кілька макетів. @ohhorob велике спасибі за рішення.
Jayshil Dave 02

2
Це працює як шарм! Але я насправді не розумію код. У вас є десь, де я можу прочитати про цілий механізм прапора?
vanleeuwenbram

Дякую, я новачок, я помістив це у своїй діяльності, яка використовує діалогове вікно EditText, тому це не в моїй діяльності xml. Я намагався поставити цей код в моїй діяльності, але отримав повідомлення про помилку: The method onCreateInputConnection(EditorInfo) of type SMSMain must override or implement a supertype method. Ви дзвоните superспочатку, тому не впевнені, в чому проблема. У вас є пропозиції? Дякую.
Azurespot

@NoniA. вам потрібно зробити підклас EditText. і в цьому класі ви повинні викликати цей метод. створити клас, який поширюється на EditText. і покласти цей метод у цей клас.
Шах

103

Відповідь Охороба в основному правильна, але його код справді надлишковий! В основному це еквівалентно цій набагато простішій версії (повний код для ледачих читачів):

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" />

Тиммммм, це тестується на 2.3?
ohhorob

1
Якщо ваш код працює на 2.3, так само і мій. Вони майже однакові, і я базую свій або ваш код, тож спасибі! Чи є ідіосинкразії 2.3, які не є в 4.0? Стандартним "без дій із багаторядковими редагуваннями" є навмисна поведінка, додана Google.
Timmmm

5
Я спробував це на 2.3 (і 4.x), і це спрацювало для мого додатка.
mlc

2
@ matej.smitala Так, ви не можете мати обидва.
Timmmm

1
Після годин пошуку найкращого рішення це здається найкращим та найпростішим способом досягнення багаторядкового редагування тексту без клавіші Enter.
micnguyen

56

Альтернативним рішенням для підкласу класу EditText є налаштування вашого екземпляра EditText таким чином:

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

Принаймні, це працює для мене на Android 4.0. Він налаштовує екземпляр EditText таким чином, що користувач редагує однорядковий рядок, який відображається з м’яким перенесенням у декілька рядків, навіть якщо встановлено дію IME.


2
@Futzilogik: Ви, сер, заслуговуєте набагато більше голосів! Ця відповідь була порятунком життя і простою. Я маю на увазі, omg wow. Мені б хотілося, щоб я проголосував не раз. Дуже дякую!
Swayam

3
Я працюю на 4.4.2, і це не спрацювало для мене чи, принаймні, для мого способу це зробити. Я зробив це лише в XML, тому, можливо, це проблема. Я налаштував inputType на "textEmailAddress | textMultiLine", прокручую горизонтально до false, maxLines до 500 (файл xml), singleLine до false і imeOptions до actionNext. Я спробував видалити "textMultiLine" з типу вводу. За допомогою textMultiLine я отримую клавішу ENTER на клавіатурі, і без неї все залишається в одному рядку і все ще прокручується горизонтально. Це здавалося найпростішим рішенням, але наведене вище працює для мене, тому поки що з ним.
реактивне ядро

6
Щодо мого попереднього коментаря (неможливо його редагувати), підозрюючи, що це або проблема з невстановленням MAX_VALUE, або просто їх зміна після створення редагувального тексту, я спробував ввести код, як зазначено тут, і це працює! Я просто хотів розміщувати повідомлення для інших, ви не можете зробити це в XML (або я все одно не міг). Інші налаштування: singleLine = false, imeOptions = actionNext, inputType = textEmailAddress (без багаторядкової лінії).
реактивне ядро

працює дуже добре. Це хороший приклад вдосконалення старої відповіді !!
nPn

Працює для мене на Galaxy S5, на якому працює Lollipop. Чудове рішення. Дивно, що встановлення горизонтальної прокрутки в xml не дає однакового ефекту
Скотт Біркстед

7

Після попередньої відповіді

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"/> 

5

для дії "Готово" ви можете використовувати:

XML

android:inputType="text|textCapSentences"    

ЯВА

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

Я сподіваюся, це допоможе вам.


1

Очевидно, що відповідь на вихідне запитання - Так, але я вважаю, що команда Android намагається змусити розробників трохи задуматися над тим, як вони використовують багаторядковий EditText. Вони хочуть, щоб клавіша Enter додавала нові рядки, і, ймовірно, очікують, що ви надасте кнопку або інший спосіб введення, щоб підняти подію, яку ви закінчили редагувати.

У мене така сама проблема, і я очевидним рішенням було просто додати готову кнопку і дозволити кнопці Enter ввести нові рядки.


Вибачте, можливо, я недостатньо чітко розказав своє запитання .. кілька рядків призначені для м’якого обертання однорядкового вводу. тобто символи нового рядка заборонені.
ohhorob

@Mullins: Ви додали власну кнопку "готово" до клавіатури SoftInput? Як ви це зробили, зберігаючи "Enter"?
alex.veprik

Ні. Я створив готову кнопку на інтерфейсі, окремо від клавіатури.
Маллінз

1
Ну, можливо, команда Android повинна слідувати власним порадам і зробити так, щоб кнопка дії багаторядкового TextEdit у програмі обміну повідомленнями створювала нові рядки, а не надсилала повідомлення.
Timmmm

0

Використовуйте ці атрибути у своєму XML.

android: inputType = "textImeMultiLine"

android: imeOptions = "actionDone"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.