Android - Ручка “Enter” в редактируемом тексте
-
18-09-2019 - |
Вопрос
Мне интересно, есть ли способ справиться с пользовательским нажатием Войти при вводе в EditText
, что-то вроде HTML-события onSubmit.
Также интересно, есть ли способ управлять виртуальной клавиатурой таким образом, чтобы кнопка "Готово" была помечена как-то иначе (например, "Перейти") и выполняла определенное действие при нажатии (опять же, как onSubmit).
Решение
Мне интересно, есть ли способ обработать нажатие пользователя Войти во время ввода текста редактирования, что-то вроде HTML-события onSubmit.
ДА.
Также интересно, есть ли способ манипулировать виртуальной клавиатурой таким образом, чтобы кнопка "Готово" была помечена как-то иначе (например "Перейти") и выполняет определенное действие при нажатии (опять же, как при отправке).
Тоже да.
Вам захочется взглянуть на android:imeActionId
и android:imeOptions
атрибуты, плюс setOnEditorActionListener()
метод, весь на TextView
.
Чтобы изменить текст кнопки "Готово" на пользовательскую строку, используйте:
mEditText.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER);
Другие советы
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 "Bluetooth Chat".Замените выделенные жирным шрифтом части , которые гласят "пример" с вашими собственными переменными и методами.
Сначала импортируйте то, что вам нужно, в основное действие, где вы хотите, чтобы кнопка возврата выполняла что-то особенное:
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import android.view.KeyEvent;
Теперь создайте переменную типа TextView.OnEditorActionListener для вашего ключа возврата (здесь я использую exampleListener - список примеров);
TextView.OnEditorActionListener exampleListener = new TextView.OnEditorActionListener(){
Затем вам нужно сообщить слушателю две вещи о том, что делать при нажатии кнопки возврата.Ему нужно знать, о каком EditText мы говорим (здесь я использую Просмотр примера), и затем ему нужно знать, что делать при нажатии клавиши Enter (здесь, example_confirm() пример_подтверждения()).Если это последний или единственный текст редактирования в вашем Действии, он должен выполнять то же самое, что и метод onClick для вашей кнопки Отправки (или OK, Подтвердить, Отправить, Сохранить и т.д.).
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).;
exampleView.setOnEditorActionListener(exampleListener);
Аппаратные клавиатуры всегда выдают события ввода, но программные клавиатуры возвращают разные ActionID и null в однострочных текстах редактирования.Этот код отвечает каждый раз, когда пользователь нажимает enter в EditText, на который настроен этот прослушиватель, независимо от EditText или типа клавиатуры.
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
}
};
Клавиша enter по умолчанию отображается в singleLine= false в виде изогнутой стрелки клавиатуры ввода.Когда singleLine=true в последнем EditText, ключ говорит "ГОТОВО", а в EditTexts перед ним написано "ДАЛЕЕ".По умолчанию такое поведение одинаково для всех эмуляторов vanilla, Android и Google.Атрибут scrollHorizontal не имеет никакого значения.Нулевой тест важен, потому что реакция телефонов на мягкие вводы остается за производителем, и даже в эмуляторах эмуляторы уровня vanilla 16 реагируют на длинные мягкие вводы в многострочных и горизонтальных текстах редактирования с помощью ActionID NEXT и null для события.
Я знаю, что этому уже год, но я только что обнаружил, что это идеально подходит для EditText .
EditText textin = (EditText) findViewById(R.id.editText1);
textin.setInputType(InputType.TYPE_CLASS_TEXT);
Это предотвращает что угодно, кроме текста и пробела.Я не мог ввести вкладку, "return" (" ") или что-нибудь еще.
На этой странице точно описано, как это сделать.
https://developer.android.com/training/keyboard-input/style.html
Установите android: Возможности использования затем вы просто проверяете ActionID ( Идентификатор действия ) в onEditorAction.Таким образом, если вы установите для imeOptions значение 'actionDone', то вы будете проверять наличие 'ActionID == EditorInfo.IME_ACTION_DONE' в onEditorAction .Кроме того, не забудьте установить android:inputType.
Вот текст редактирования из примера, приведенного выше:
<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) Установить параметры (int) функция.Вот OnEditorActionListener из примера, приведенного выше:
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;
}
});
Просто в качестве дополнения к ответу Чада (который сработал для меня почти идеально) я обнаружил, что мне нужно добавить проверку типа действия KeyEvent, чтобы предотвратить повторное выполнение моего кода (один раз при нажатии клавиши вверх и один раз при нажатии клавиши вниз).
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN)
{
// your code here
}
Видишь http://developer.android.com/reference/android/view/KeyEvent.html для получения информации о повторяющихся действиях (удерживание клавиши enter) и т.д.
У меня была похожая цель.Я хотел разрешить нажатие клавиши "Enter" на клавиатуре (которую я хотел настроить) в AutoCompleteTextView, который расширяет TextView.Я пробовал различные решения, описанные выше, и они, казалось, сработали.НО у меня возникли некоторые проблемы, когда я переключил тип ввода на своем устройстве (Nexus 4 с AOKP ROM) с SwiftKey 3 (где он работал идеально) на стандартную клавиатуру Android (где вместо обработки моего кода из прослушивателя после нажатия клавиши "Enter" вводилась новая строка.Мне потребовалось некоторое время, чтобы справиться с этой проблемой, но я не знаю, будет ли это работать при всех обстоятельствах, независимо от того, какой тип ввода вы используете.
Итак, вот мое решение:
Установите для атрибута типа ввода TextView в xml значение "текст".:
android:inputType="text"
Настройте метку клавиши "Enter" на клавиатуре:
myTextView.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER);
Установите OnEditorActionListener в TextView для OnEditorActionListener:
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
<EditText
android:id="@+id/edittext_additem"
...
android:imeOptions="actionDone"
/>
Затем в вашем Java-коде добавьте OnEditorActionListener к тому же EditText
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" клавише ввода.Клавиша ввода на клавиатуре изменится с "Enter" на "Done".Таким образом, когда нажата клавиша Enter, это вызовет это действие, и таким образом вы справитесь с ним.
Вы тоже можете это сделать..
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;
}
});
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;
}
});
У меня это работает очень хорошо
Кроме того, скрыть клавиатуру
работает идеально
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) == '\n') {
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 для нажатия клавиши
@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:
@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 вверху:
import android.view.KeyEvent;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.TextView;
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 - файл
<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" />
Это должно сработать
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( "\n" ) ){
input.setText("Enter was pressed!");
}
}
});
Это прекрасно работает на телефонах LG Android.Это предотвращает ENTER
и другие специальные символы, которые должны интерпретироваться как обычные символы. Next
или Done
кнопка появляется автоматически и ENTER
работает, как и ожидалось.
edit.setInputType(InputType.TYPE_CLASS_TEXT);
Вот простая статическая функция, которую вы можете добавить в свой Utils
или Keyboards
класс, который будет выполнять код, когда пользователь нажимает клавишу возврата на аппаратной или программной клавиатуре.Это модифицированная версия превосходного ответа @earlcasper
/**
* Return a TextView.OnEditorActionListener that will execute code when an enter is pressed on
* the keyboard.<br>
* <code>
* myTextView.setOnEditorActionListener(Keyboards.onEnterEditorActionListener(new Runnable()->{
* Toast.makeText(context,"Enter Pressed",Toast.LENGTH_SHORT).show();
* }));
* </code>
* @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;
}
};
}
inputType в текстовом поле должно быть text
для того, чтобы то, что сказал CommonsWare, сработало.Просто попробовал все это, до пробной версии не было inputType, и ничего не работало, Enter продолжал регистрироваться как soft enter.После inputType = text
, все, включая setImeLabel, работало.
Пример : android:inputType="text"
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;
}
});
Введите этот код в свой редактор, чтобы он мог импортировать необходимые модули.
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;
}
});
Надежный способ ответить на <enter> в редактируемом тексте с помощью Просмотр текста, а LocalBroadcastManager - менеджер локальной рассылки, и a Приемник широковещательной передачи.Вам нужно добавить библиотека поддержки версии 4 чтобы использовать LocalBroadcastManager.Я использую учебник по адресу vogella.com:7.3 "События локальной трансляции с помощью LocalBroadcastManager" из-за его полного сжатого примера кода.В onTextChanged до того , как является индекс окончания изменения до изменения>;минус начало.Когда в TextWatcher поток пользовательского интерфейса занят обновлением редактируемого EditText , поэтому мы отправляем намерение разбудить BroadcastReceiver, когда поток пользовательского интерфейса завершит обновление EditText.
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)=='\n') {
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
Добавьте эти зависимости, и это должно сработать:
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
На этот вопрос еще не был дан ответ с помощью Butterknife
МАКЕТ XML
<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-ПРИЛОЖЕНИЕ
@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;
}
Котлин
editTextVar?.setOnKeyListener { v, keyCode, event ->
if((event.action == KeyEvent.ACTION_DOWN)
&& (event.keyCode == KeyEvent.KEYCODE_ENTER)){
//Do something, such as loadJob()
loadJob()
return@setOnKeyListener true
}
false
}