带有完成操作按钮的多行输入框

145

是否可以同时设置 android:inputType="textMultiLine"android:imeOptions="actionDone" 属性来创建一个多行文本框,并让键盘上的操作按钮显示“完成”而不是“回车”(Enter)?

我想要一个多行编辑框,并希望键盘上的操作按钮是“完成”,而不是“回车”(Carriage Return),但似乎无法实现。


尝试使用多行EditText和Button组合在一起的复合小部件怎么样? - C--
1
请将以下与编程有关的内容从英语翻译成中文。仅返回已翻译的文本:类似于https://dev59.com/PW445IYBdhLWcg3wJ298 - larham1
17个回答

2

如果您在使用input选项textImeMultiline和imeoptions flagnext以及actionnext时,就会获得下一步按钮而不是回车符。


2

虽然其他解决方案对我都没有用,但是下面这个方案非常有效,让我省去了数天的搜索时间,当然还加入了我的一些变化。不幸的是,我不记得从哪里得到这段代码,因此无法给予作者应有的荣誉。

在你的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;
        }
});

可能来自 https://gist.github.com/Dogesmith/2b98df97b4fca849ff94 - Naz
可能来自 https://gist.github.com/Dogesmith/2b98df97b4fca849ff94 - Naz
可能来自 https://gist.github.com/Dogesmith/2b98df97b4fca849ff94 - Naz

1
我使用的是4.x版本,并尝试调用setHorizontallyScrolling()(带或不带setLine()或setMaxLines()),以及许多不同的XML配置来显示完成按钮。但它们都没有起作用。最重要的是,如果您的EditText是多行的,则Android始终希望显示换行符而不是“完成”按钮,除非您在此方面进行了一些黑客处理。
我发现最简单的解决方案是在这里:https://dev59.com/PW445IYBdhLWcg3wJ298#12570003。该解决方案将使Android放弃强制设置IME_FLAG_NO_ENTER_ACTION标志以供多行视图使用,从而导致完成按钮消失。

0

我也曾经苦苦挣扎了很长时间,但最终我找到了解决方案!

只需创建一个自定义的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();
    }
}

这个类可以去除换行符(\n),像textMultiline一样包装文本,并允许您用ImeAction替换Enter按钮 ;).

您只需要在XML中调用它,而不是传统的EditText类。

这里的逻辑解释如下:

  • 将EditText设置为singleLine,以便显示ImeAction按钮而不是Enter。
  • 删除水平滚动条,使文本在视图末尾时转到下一行。
  • 使用onGlobalLayoutListener监视布局更改,并将其“line”参数设置为editText当前文本的“lineCount”。这就是刷新其高度的方法。

0

如果你使用DataBinding,你应该创建一个能捕捉操作的方法。参见https://dev59.com/1VcO5IYBdhLWcg3wvUMp#52902266

一些扩展方法的文件,例如,BindingAdapters.kt:

@BindingAdapter("inputType", "action")
fun EditText.setMultiLineCapSentencesAndDoneAction(inputType: Int, callback: OnActionListener?) {
    setRawInputType(inputType)
    if (callback == null) setOnEditorActionListener(null)
    else setOnEditorActionListener { v, actionId, event ->
        if (actionId == EditorInfo.IME_ACTION_DONE ||
            event?.keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN
        ) {
            callback.enterPressed()
            return@setOnEditorActionListener true
        }
        return@setOnEditorActionListener false
    }
}

interface OnActionListener {
    fun enterPressed()
}

然后在XML中:

<data>
    <variable
        name="viewModel"
        type="YourViewModel" />

    <import type="android.text.InputType" />
</data>

<EditText
    android:imeOptions="actionDone"
    android:inputType=""
    app:action="@{() -> viewModel.send()}"
    app:inputType="@{InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE}" />

0

对于 Compose UI,代码如下:

TextField(
   ...
   keyboardOptions = KeyboardOptions(
       imeAction = ImeAction.Done
   ),
   ...
)

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接