带有完成操作按钮的多行EditText

时间:2010-06-06 23:42:32

标签: android

是否可以设置EditText窗口小部件,同时设置android:inputType="textMultiLine"android:imeOptions="actionDone"

我想要一个多行编辑框,键盘上的操作按钮完成,而不是回车(回车),但它似乎没有工作..

提前致谢

16 个答案:

答案 0 :(得分:151)

使用

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);

和XML:

android:inputType="textMultiLine"

答案 1 :(得分:49)

来自android文档:'“textMultiLine”     普通文本键盘,允许用户输入包含换行符(回车)的长文本字符串。'因此,如果您想要“完成”按钮,则textMultiLine属性不合适在键盘上。

使用完成按钮获取多行(在本例中为3行)输入字段的简单方法是使用EditText和

android:lines="3" 
android:scrollHorizontally="false" 

但是,由于某些原因,如果我在代码中执行这些设置而不是布局文件(在onCreate中),这仅适用于我

TextView tv = (TextView)findViewById(R.id.editText);
if (tv != null) {
    tv.setHorizontallyScrolling(false);
    tv.setLines(3);
}

我希望这对某人有所帮助,因为花了很长时间才弄明白。如果您找到了一种方法,可以从清单中找到它,请告诉我们。

答案 2 :(得分:24)

工作示例! 创建以下支持此功能的自定义EditText类,并使用xml文件中的类。工作代码:

package com.example;

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

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;
   }
}

<com.example.ActionEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:imeOptions="actionDone"
       android:inputType="textAutoCorrect|textCapSentences|textMultiLine" />

答案 3 :(得分:7)

我认为这是做事的方法。拥有android:inputType="textMultiLine"android:imeOptions="actionDone"会使输入键功能变得模糊不清。请记住,您可以使用android:lines="10"并可能删除android:inputType="textMultiLine",但取决于您希望实现的目标,有时您只需要android:inputType="textMultiLine"并且没有替代它。

EditText ed=new EditText(this);
ed.setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if(keyCode == KeyEvent.KEYCODE_ENTER){
                //do your stuff here
            }
            return false;
        }
});

答案 4 :(得分:5)

这似乎对我很有用

int lineNum = 2;
mEditText.setHorizontallyScrolling(false);
mEditText.setLines(3);

答案 5 :(得分:3)

简短回答:不,我认为在API级别11(3.0)之前不可能。

这里出现了同样的问题(在对已接受的答案的评论中讨论过):

Android Soft keyboard action button

从最终评论:

  

查看手机上的一些应用程序,最后将多行方框设为最后,其下方有一个可见的“完成”或“发送”按钮(例如电子邮件应用)。

答案 6 :(得分:3)

解决这种情况的简单方法:

  • 将此属性保留在EditText上:

    android:inputType="textMultiLine" 
    android:scrollHorizontally="false"
    
  • 然后添加此代码以仅在按下ENTER时隐藏键盘:

    editText.setOnEditorActionListener(new OnEditorActionListener() 
    {
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) 
        {
            editText.setSelection(0);
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);      
            return true;
         } 
         else 
         {
            return false;
         }
         }
    });
    

答案 7 :(得分:2)

如果不是屏幕键盘的外观,你可以简单地在键盘上放置一个输入监听器,并在用户输入换行符时触发“完成”状态。

答案 8 :(得分:2)

如果您使用带有imeoptions flagnext和actionnext的输入选项textImeMultiline,则会获得下一个按钮而不是cariage返回

答案 9 :(得分:1)

我在4.x上尝试调用setHorizo​​ntallyScrolling()(带或不带setLine()或setMaxLines()),以及许多不同的XML配置来显示完成按钮。他们都没有工作。最重要的是,如果您的EditText是多行的,Android总是希望显示回车而不是&#34;完成&#34;按钮,除非你在这周围进行一些黑客攻击。

我发现不太复杂的解决方案并不涉及重新映射回车的行为:https://stackoverflow.com/a/12570003/3268329。这个解决方案将使Android无情地强制要求为多行视图强制设置IME_FLAG_NO_ENTER_ACTION标志,这会导致Done按钮消失。

答案 10 :(得分:1)

虽然其他解决方案都没有对我有用,但以下工作非常漂亮,并且在日常和谷歌上搜索了几天,当然还有一些我自己的曲折。不幸的是,我不记得我从哪里获得了代码,所以不能给作者他/她应得的信誉。

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

答案 11 :(得分:1)

Kotlin扩展功能示例,用于在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()

答案 12 :(得分:1)

要在Kotlin中进行此操作(还可以选择应用其他配置,例如textCapSentences,则可以使用此扩展功能:

// To use this, do NOT set inputType on the EditText in the 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()

答案 13 :(得分: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();
    }
}

此类删除lineBreaks(\ n),将文本包装为textMultiline将执行的操作,并允许您通过ImeAction替换Enter按钮;)。

您只需要在XML中调用它而不是经典的EditText类。

解释这里的逻辑:

  • 将EditText设置为singleLine,以便能够显示ImeAction按钮而不是Enter。
  • 移除水平滚动以使文本在到达视图末尾时转到下一行。
  • 使用onGlobalLayoutListener观察布局更改,并设置它&#34; line&#34; &#34; lineCount&#34;的参数editText保存的当前文本。这就是刷新它的高度。

答案 14 :(得分:0)

工作解决方案就在这里,创建你的自定义EditTextView(只是扩展一个textview)并覆盖onInputConnection,你可以在这里找到一段代码:Multiline EditText with Done SoftInput Action Label on 2.3

答案 15 :(得分:0)

如果您使用 DataBinding,您应该创建一个可以捕获操作的方法。另见https://stackoverflow.com/a/52902266/2914140

一些带有扩展方法的文件,例如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}" />