Многострочный EditText с кнопкой «Готово» - PullRequest
93 голосов
/ 07 июня 2010

Можно ли иметь виджет EditText с установленными android:inputType="textMultiLine" и android:imeOptions="actionDone" одновременно?

Мне бы хотелось, чтобы окно редактирования в несколько строк содержало кнопку «Готово» на клавиатуре, а не «Ввод» (возврат каретки), но, похоже, она не работает ..

Заранее спасибо

Ответы [ 15 ]

1 голос
/ 15 октября 2018

Пример функции расширения Kotlin для включения действия Done и определенной комбинации типов ввода в EditTextExt.kt:

// To use this, do NOT set inputType on the EditText in the XML layout
fun EditText.setMultiLineCapSentencesAndDoneAction() {
    imeOptions = EditorInfo.IME_ACTION_DONE
    setRawInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
}

Тогда использование:

myEditText.setMultiLineCapSentencesAndDoneAction()
1 голос
/ 15 февраля 2017

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

В вашем коде Java:

////////////Code to Hide SoftKeyboard on Enter (DONE) Press///////////////
editText.setRawInputType(InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD|InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeActionLabel("DONE",EditorInfo.IME_ACTION_DONE);              //Set Return Carriage as "DONE"
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);

editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) 
    {
                if (event == null) {
                    if (actionId == EditorInfo.IME_ACTION_DONE) {
                        // Capture soft enters in a singleLine EditText that is the last EditText
                        // This one is useful for the new list case, when there are no existing ListItems
                        editText.clearFocus();
                        InputMethodManager inputMethodManager = (InputMethodManager)  getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
                        inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
                    }

                    else if (actionId == EditorInfo.IME_ACTION_NEXT) {
                        // Capture soft enters in other singleLine EditTexts
                    } else if (actionId == EditorInfo.IME_ACTION_GO) {
                    } else {
                        // Let the system handle all other null KeyEvents
                        return false;
                    }
                } 
        else if (actionId == EditorInfo.IME_NULL) {
                    // Capture most soft enters in multi-line EditTexts and all hard enters;
                    // They supply a zero actionId and a valid keyEvent rather than
                    // a non-zero actionId and a null event like the previous cases.
                    if (event.getAction() == KeyEvent.ACTION_DOWN) {
                        // We capture the event when the key is first pressed.
                    } else {
                        // We consume the event when the key is released.
                        return true;
                    }
                } 
        else {
                    // We let the system handle it when the listener is triggered by something that
                    // wasn't an enter.
                    return false;
                }
                return true;
        }
});
1 голос
/ 03 февраля 2015

Я нахожусь на 4.x и попытался вызвать setHorizontallyScrolling () (с или без setLine () или setMaxLines ()), а также множество различных конфигураций XML, чтобы отобразить кнопку Done.Никто из них не работал.Суть в том, что если ваш EditText является многострочным, Android всегда будет хотеть показать возврат каретки вместо кнопки «Готово», если только вы не предпримете какой-либо хакерской манеры.

Наименьшее сложное решение, которое я обнаружил, которое не включает переопределение поведения возврата каретки, здесь: https://stackoverflow.com/a/12570003/3268329. Это решение сведет на нет постоянное желание Android принудительно установить флаг IME_FLAG_NO_ENTER_ACTION для несколькихвиды линий, что приводит к исчезновению кнопки Готово.

0 голосов
/ 05 февраля 2016

Рабочее решение уже здесь, создайте свой собственный EditTextView (просто расширите текстовое представление) и переопределите onInputConnection с помощью кода, который вы найдете в принятом ответе здесь: Многострочный EditText с меткой действия Done SoftInput на 2.3

0 голосов
/ 13 января 2016

Я тоже долго боролся, но наконец-то нашел решение!

Просто создайте собственный класс EditText следующим образом:

public class EditTextImeMultiline extends EditText {

    public void init() {
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                for (int i = s.length(); i > 0; i--)
                    if (s.subSequence(i - 1, i).toString().equals("\n"))
                        s.replace(i - 1, i, "");
            }
        });
        setSingleLine();
        setHorizontallyScrolling(false);
        this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                EditTextImeMultiline.this.setLines(EditTextImeMultiline.this.getLineCount());
            }
        });
    }

    public EditTextImeMultiline(Context context) {
        super(context);
        init();
    }

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

    public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }
}

Этот класс удаляет lineBreaks (\ n), переносит текст так, как это делает textMultiline, и позволяет заменить кнопку Enter на ImeAction;).

Вам просто нужно вызвать ее в своем XML-коде вместо классического класса EditText.

Чтобы объяснить логику здесь:

  • Установите EditText как одну строку, чтобы можно было показывать кнопку ImeAction вместо Enter.
  • Удалите горизонтальную прокрутку, чтобы текст шелна следующую строку при достижении конца представления.
  • Наблюдайте за изменениями макета с помощью onGlobalLayoutListener и установите для его параметра "line" значение "lineCount" текущего текста, содержащегося в editText.Это то, что обновляет его высоту.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...