Android - Handle “Enter” in an EditText
我想知道是否有办法处理用户在输入
还想知道是否有办法操纵虚拟键盘,使"完成"按钮被标记为其他东西(例如"Go")并在点击时执行某个动作(再次,如onSubmit)。
I am wondering if there is a way to
handle the user pressing Enter while
typing in an EditText, something like
the onSubmit HTML event.
是。
Also wondering if there is a way to
manipulate the virtual keyboard in
such a way that the"Done" button is
labeled something else (for example
"Go") and performs a certain action
when clicked (again, like onSubmit).
也是的。
您将需要在
要将"完成"按钮的文本更改为自定义字符串,请使用:
1 | mEditText.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER); |
1 2 3 4 5 6 7 8 9 10 11 12 13 | final EditText edittext = (EditText) findViewById(R.id.edittext); edittext.setOnKeyListener(new OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { // If the event is a key-down event on the"enter" button if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { // Perform action on key press Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show(); return true; } return false; } }); |
这是你做的。它也隐藏在Android Developer的示例代码"蓝牙聊天"中。用您自己的变量和方法替换说"example"的粗体部分。
首先,将您需要的内容导入主Activity,您希望返回按钮执行一些特殊操作:
1 2 3 | import android.view.inputmethod.EditorInfo; import android.widget.TextView; import android.view.KeyEvent; |
现在,为返回键创建一个TextView.OnEditorActionListener类型的变量(这里我使用exampleListener);
1 | TextView.OnEditorActionListener exampleListener = new TextView.OnEditorActionListener(){ |
然后,您需要告诉听众有关按下返回按钮时要执行的操作的两件事。它需要知道我们正在谈论的EditText(这里我使用exampleView),然后它需要知道当按下Enter键时该做什么(这里,example_confirm())。如果这是您的Activity中的最后一个或唯一的EditText,它应该与提交(或确定,确认,发送,保存等)按钮的onClick方法相同。
1 2 3 4 5 6 7 | public boolean onEditorAction(TextView exampleView, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) { example_confirm();//match this behavior to your 'Send' (or Confirm) button } return true; } |
最后,设置监听器(最有可能在你的onCreate方法中);
1 | exampleView.setOnEditorActionListener(exampleListener); |
硬件键盘总是产生输入事件,但软件键盘在singleLine EditTexts中返回不同的actionID和null。无论EditText或键盘类型如何,每次用户按下此侦听器已设置的EditText时,此代码都会响应。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import android.view.inputmethod.EditorInfo; import android.view.KeyEvent; import android.widget.TextView.OnEditorActionListener; listener=new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView view, 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. else if (actionId==EditorInfo.IME_ACTION_NEXT); // Capture soft enters in other singleLine EditTexts else return false; // Let system handle all other null KeyEvents } 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 key is first pressed. else return true; // We consume the event when the key is released. } else return false; // We let the system handle it when the listener // is triggered by something that wasn't an enter. // Code from this point on will execute whenever the user // presses enter in an attached view, regardless of position, // keyboard, or singleLine status. if (view==multiLineEditText) multiLineEditText.setText("You pressed enter"); if (view==singleLineEditText) singleLineEditText.setText("You pressed next"); if (view==lastSingleLineEditText) lastSingleLineEditText.setText("You pressed done"); return true; // Consume the event } }; |
在singleLine = false中输入键的默认外观给出一个弯曲的箭头输入键盘。当最后一个EditText中的singleLine = true时,键表示DONE,而在之前的EditTexts上表示NEXT。默认情况下,此行为在所有vanilla,android和Google模拟器中都是一致的。 scrollHorizo??ntal属性没有任何区别。空值测试非常重要,因为手机对软输入的响应留给了制造商,即使在模拟器中,vanilla Level 16仿真器也会响应多行中的长软输入和scrollHorizo??ntal EditTexts,其actionId为NEXT,为null事件。
我知道这已经有一年了,但我发现这对EditText非常有效。
1 2 | EditText textin = (EditText) findViewById(R.id.editText1); textin.setInputType(InputType.TYPE_CLASS_TEXT); |
除了文本和空间之外,它可以防止任我无法标签,"返回"(" n")或其他任何东西。
此页面准确描述了如何执行此操作。
https://developer.android.com/training/keyboard-input/style.html
设置android:imeOptions然后你只需检查onEditorAction中的actionId。因此,如果您将imeOptions设置为'actionDone',那么您将在onEditorAction中检查'actionId == EditorInfo.IME_ACTION_DONE'。另外,请确保设置android:inputType。
这是上面链接的示例中的EditText:
1 2 3 4 5 6 7 | <EditText android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/search_hint" android:inputType="text" android:imeOptions="actionSend" /> |
您也可以使用setImeOptions(int)函数以编程方式设置它。这是上面链接的示例中的OnEditorActionListener:
1 2 3 4 5 6 7 8 9 10 11 12 | EditText editText = (EditText) findViewById(R.id.search); editText.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { boolean handled = false; if (actionId == EditorInfo.IME_ACTION_SEND) { sendMessage(); handled = true; } return handled; } }); |
就像Chad的回复(对我来说几乎完美无缺)的附录一样,我发现我需要在KeyEvent动作类型上添加一个检查,以防止我的代码执行两次(一次在键盘上,一次在键盘上)事件)。
1 2 3 4 | if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) { // your code here } |
有关重复操作事件(按住回车键)等信息,请参阅http://developer.android.com/reference/android/view/KeyEvent.html。
我有一个类似的目的。我想解决在扩展TextView的AutoCompleteTextView中按下键盘上的"Enter"键(我想自定义)。我从上面尝试了不同的解决方案,它们似乎有效。但是当我将我的设备上的输入类型(带有AOKP ROM的Nexus 4)从SwiftKey 3(它完美地工作)切换到标准的Android键盘时,我遇到了一些问题(而不是从听众处理我的代码,新的一行是按"Enter"键后进入。我花了一段时间来处理这个问题,但我不知道它是否适用于所有情况,无论你使用哪种输入类型。
所以这是我的解决方案:
将xml中TextView的输入类型属性设置为"text":
1 | android:inputType="text" |
自定义键盘上"Enter"键的标签:
1 | myTextView.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER); |
将OnEditorActionListener设置为TextView:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | myTextView.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { boolean handled = false; if (event.getAction() == KeyEvent.KEYCODE_ENTER) { // Handle pressing"Enter" key here handled = true; } return handled; } }); |
我希望这可以帮助别人避免我遇到的问题,因为他们差点让我疯狂。
在xml中,将imeOptions属性添加到editText
1 2 3 4 5 | <EditText android:id="@+id/edittext_additem" ... android:imeOptions="actionDone" /> |
然后,在Java代码中,将OnEditorActionListener添加到同一EditText
1 2 3 4 5 6 7 8 9 10 | mAddItemEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if(actionId == EditorInfo.IME_ACTION_DONE){ //do stuff return true; } return false; } }); |
这是解释 -
imeOptions = actionDone会将"actionDone"分配给EnterKey。键盘中的EnterKey将从"Enter"更改为"Done"。因此,当按下Enter键时,它将触发此操作,因此您将处理它。
你也可以这样做..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | editText.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { Log.i("event","captured"); return false; } return false; } }); |
1 2 3 4 5 6 7 8 9 10 11 | password.setOnEditorActionListener(new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0); submit.performClick(); return true; } return false; } }); |
对我来说非常好
另外隐藏键盘
工作得很好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public class MainActivity extends AppCompatActivity { TextView t; Button b; EditText e; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); b = (Button) findViewById(R.id.b); e = (EditText) findViewById(R.id.e); e.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (before == 0 && count == 1 && s.charAt(start) == ' ') { b.performClick(); e.getText().replace(start, start + 1,""); //remove the <enter> } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void afterTextChanged(Editable s) {} }); b.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { b.setText("ok"); } }); } |
}
工作得很好
首先,你必须设置EditText听取按键
1 2 3 4 5 6 7 8 9 10 | @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set the EditText listens to key press EditText edittextproductnumber = (EditText) findViewById(R.id.editTextproductnumber); edittextproductnumber.setOnKeyListener(this); } |
其次,在按键时定义事件,例如,设置TextView文本的事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // TODO Auto-generated method stub // Listen to"Enter" key press if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { TextView textviewmessage = (TextView) findViewById(R.id.textViewmessage); textviewmessage.setText("You hit 'Enter' key"); return true; } return false; } |
最后,不要忘记在顶部导入EditText,TextView,OnKeyListener,KeyEvent:
1 2 3 4 | import android.view.KeyEvent; import android.view.View.OnKeyListener; import android.widget.EditText; import android.widget.TextView; |
1 2 3 4 5 6 7 8 9 10 11 | editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId != 0 || event.getAction() == KeyEvent.ACTION_DOWN) { // Action return true; } else { return false; } } }); |
XML
1 2 3 4 5 6 7 8 | <EditText android:id="@+id/editText2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/password" android:imeOptions="actionGo|flagNoFullscreen" android:inputType="textPassword" android:maxLines="1" /> |
这应该工作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | input.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) {} @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if( -1 != input.getText().toString().indexOf(" " ) ){ input.setText("Enter was pressed!"); } } }); |
这在LG Android手机上运行良好。它可以防止
1 | edit.setInputType(InputType.TYPE_CLASS_TEXT); |
文本字段上的InputType必须为
示例:
在编辑器中键入此代码,以便它可以导入必要的模块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | query.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { if(actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_DONE || keyEvent.getAction() == keyEvent.ACTION_DOWN || keyEvent.getAction() == keyEvent.KEYCODE_ENTER) { // Put your function here ---! return true; } return false; } }); |
这是一个简单的静态函数,您可以将其放入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /** * Return a TextView.OnEditorActionListener that will execute code when an enter is pressed on * the keyboard. * <wyn> * myTextView.setOnEditorActionListener(Keyboards.onEnterEditorActionListener(new Runnable()->{ * Toast.makeText(context,"Enter Pressed",Toast.LENGTH_SHORT).show(); * })); * </wyn> * @param doOnEnter A Runnable for what to do when the user hits enter * @return the TextView.OnEditorActionListener */ public static TextView.OnEditorActionListener onEnterEditorActionListener(final Runnable doOnEnter){ return (__, actionId, event) -> { if (event==null) { if (actionId == EditorInfo.IME_ACTION_DONE) { // Capture soft enters in a singleLine EditText that is the last EditText. doOnEnter.run(); return true; } else if (actionId==EditorInfo.IME_ACTION_NEXT) { // Capture soft enters in other singleLine EditTexts doOnEnter.run(); return true; } else { return false; // Let system handle all other null KeyEvents } } 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 key is first pressed. return true; } else { doOnEnter.run(); return true; // We consume the event when the key is released. } } else { // We let the system handle it when the listener // is triggered by something that wasn't an enter. return false; } }; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | final EditText edittext = (EditText) findViewById(R.id.edittext); edittext.setOnKeyListener(new OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { // If the event is a key-down event on the"enter" button if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { // Perform action on key press Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show(); return true; } return false; } }); |
在EditText中响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.text.Editable; //in onCreate: editText.addTextChangedListener(new TextWatcher() { public void onTextChanged (CharSequence s, int start, int before, int count) { //check if exactly one char was added and it was an <enter> if (before==0 && count==1 && s.charAt(start)==' ') { Intent intent=new Intent("enter") Integer startInteger=new Integer(start); intent.putExtra("Start", startInteger.toString()); // Add data mySendBroadcast(intent); //in the BroadcastReceiver's onReceive: int start=Integer.parseInt(intent.getStringExtra("Start")); editText.getText().replace(start, start+1,""); //remove the <enter> //respond to the <enter> here |
添加这些depencendy,它应该工作:
1 2 3 | import android.view.KeyEvent; import android.view.View; import android.widget.EditText; |
Butterknife尚未回答这个问题
布局XML
1 2 3 4 5 6 7 8 9 10 11 12 | <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/some_input_hint"> <android.support.design.widget.TextInputEditText android:id="@+id/textinput" android:layout_width="match_parent" android:layout_height="wrap_content" android:imeOptions="actionSend" android:inputType="text|textCapSentences|textAutoComplete|textAutoCorrect"/> </android.support.design.widget.TextInputLayout> |
JAVA APP
1 2 3 4 5 6 7 8 9 | @OnEditorAction(R.id.textinput) boolean onEditorAction(int actionId, KeyEvent key){ boolean handled = false; if (actionId == EditorInfo.IME_ACTION_SEND || (key.getKeyCode() == KeyEvent.KEYCODE_ENTER)) { //do whatever you want handled = true; } return handled; } |