android EditText - закончил печатать событие - PullRequest
99 голосов
/ 09 ноября 2011

Я хочу поймать событие, когда пользователь заканчивает редактирование EditText.

Как это можно сделать?

Ответы [ 12 ]

167 голосов
/ 09 ноября 2011

Лучше, вы также можете использовать EditText onFocusChange слушатель, чтобы проверить, закончил ли пользователь редактирование: (не нужно полагаться на пользователя, нажимающего кнопку Done или Enter на программной клавиатуре)

 ((EditText)findViewById(R.id.youredittext)).setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
    /* When focus is lost check that the text field
    * has valid values.
    */
      if (!hasFocus) {
       validateInput(v);
      }
    }
 });
105 голосов
/ 09 ноября 2011

Когда пользователь завершит редактирование, он / она нажмет Done или Enter

((EditText)findViewById(R.id.youredittext)).setOnEditorActionListener(
    new EditText.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_SEARCH ||
                    actionId == EditorInfo.IME_ACTION_DONE ||
                    event != null &&
                    event.getAction() == KeyEvent.ACTION_DOWN &&
                    event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
                if (event == null || !event.isShiftPressed()) {
                   // the user is done typing. 

                   return true; // consume.
                }                
            }
            return false; // pass on to other listeners. 
        }
    }
);
49 голосов
/ 20 февраля 2015

Лично я предпочитаю автоматическую отправку после завершения ввода. Вот как вы можете обнаружить это событие.

Объявления и инициализация:

private Timer timer = new Timer();
private final long DELAY = 1000; // in ms

Слушатель, например, OnCreate ()

EditText editTextStop = (EditText) findViewById(R.id.editTextStopId);
    editTextStop.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
        }
        @Override
        public void onTextChanged(final CharSequence s, int start, int before,
                int count) {
            if(timer != null)
                timer.cancel();
        }
        @Override
        public void afterTextChanged(final Editable s) {
            //avoid triggering event when text is too short
            if (s.length() >= 3) {              

                timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        // TODO: do what you need here (refresh list)
                        // you will probably need to use
                        // runOnUiThread(Runnable action) for some specific
                        // actions
                        serviceConnector.getStopPoints(s.toString());
                    }

                }, DELAY);
            }
        }
    });

Таким образом, при изменении текста таймер начинает ждать следующих изменений. Когда они происходят, таймер отменяется, а затем запускается снова.

20 голосов
/ 09 ноября 2011

Вы можете сделать это с помощью setOnKeyListener или с помощью textWatcher, например:

Установить наблюдателя текста editText.addTextChangedListener(textWatcher);

, затем вызвать

private TextWatcher textWatcher = new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            //after text changed
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    };
4 голосов
/ 13 августа 2014

@Reno и @Vinayak B отвечают вместе, если вы хотите скрыть клавиатуру после действия

textView.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(textView.getWindowToken(), 0);
            return true;
        }
        return false;
    }
});

textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
             // your action here
        }
    }
});
4 голосов
/ 12 июня 2014

Хотя многие ответы указывают в правильном направлении, я думаю, что ни один из них не отвечает на то, о чем думал автор вопроса.Или, по крайней мере, я понял вопрос по-другому, потому что искал ответ на похожую проблему.Проблема в том, «Как узнать, когда пользователь перестает печатать без нажатия кнопки», и вызвать какое-либо действие (например, автозаполнение).Если вы хотите сделать это, запустите таймер в onTextChanged с задержкой, которую вы считаете, что пользователь прекратил печатать (например, 500-700 мс), для каждой новой буквы при запуске таймера отмените предыдущую (или, по крайней мере, используйте какой-то видотметьте, что когда они ставят галочку, они ничего не делают).Вот код, подобный тому, что я использовал:

new Timer().schedule(new TimerTask() {
  @Override
  public void run() {
     if (!running) {                            
        new DoPost().execute(s.toString());
  });
 }
}, 700);

Обратите внимание, что я изменяю флаг запуска в моей асинхронной задаче (Задача получает json с сервера для автозаполнения).

Также имейте в виду, что это создает много задач таймера (я думаю, что они запланированы в том же потоке, но вы должны это проверить), так что, вероятно, есть много мест для улучшения, но этот подход также работает, и суть в том, что вы должныиспользуйте таймер, поскольку отсутствует событие «Пользователь прекратил печатать»

2 голосов
/ 05 декабря 2014

Другой подход ... вот пример: если пользователь печатает с задержкой 600-1000 мс, вы можете считать, что он остановлен.

 myEditText.addTextChangedListener(new TextWatcher() {
             
            private String s;
            private long after;
			private Thread t;
            private Runnable runnable_EditTextWatcher = new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        if ((System.currentTimeMillis() - after) > 600)
                        {
                            Log.d("Debug_EditTEXT_watcher", "(System.currentTimeMillis()-after)>600 ->  " + (System.currentTimeMillis() - after) + " > " + s);
                            // Do your stuff
                            t = null;
                            break;
                        }
                    }
                }
            };
            
            @Override
            public void onTextChanged(CharSequence ss, int start, int before, int count) {
                s = ss.toString();
            }
            
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            
            @Override
            public void afterTextChanged(Editable ss) {
                after = System.currentTimeMillis();
                if (t == null)
                {
                    t = new Thread(runnable_EditTextWatcher);
                      t.start();
                }
            }
        });
2 голосов
/ 19 ноября 2014

Хорошо, это будет работать на 100% наверняка.

Сначала вам нужно настроить слушателя, если клавиатура отображается или скрывается.Если клавиатура показывает, то, вероятно, пользователь печатает, в противном случае закончил печатать.

final View activityRootView = findViewById(android.R.id.content);
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {

                    Rect r = new Rect();
                    //r will be populated with the coordinates of your view that area still visible.
                    activityRootView.getWindowVisibleDisplayFrame(r);

                    int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
                    if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...

                        isTyping = true;
                    } else {
//to make sure this will call only once when keyboard is hide.
                        if(isTyping){
                            isTyping = false;
                        }
                    }
            }
        });
0 голосов
/ 09 августа 2018

Я сделал что-то вроде этого абстрактного класса, который можно использовать вместо типа TextView.OnEditorActionListener.

abstract class OnTextEndEditingListener : TextView.OnEditorActionListener {

    override fun onEditorAction(textView: TextView?, actionId: Int, event: KeyEvent?): Boolean {

        if(actionId == EditorInfo.IME_ACTION_SEARCH ||
                actionId == EditorInfo.IME_ACTION_DONE ||
                actionId == EditorInfo.IME_ACTION_NEXT ||
                event != null &&
                event.action == KeyEvent.ACTION_DOWN &&
                event.keyCode == KeyEvent.KEYCODE_ENTER) {

            if(event == null || !event.isShiftPressed) {
                // the user is done typing.
                return onTextEndEditing(textView, actionId, event)
            }
        }
        return false // pass on to other listeners
    }

    abstract fun onTextEndEditing(textView: TextView?, actionId: Int, event: KeyEvent?) : Boolean
}
0 голосов
/ 15 февраля 2016

Я закончил ее с той же проблемой, и я не мог использовать решение с onEditorAction или onFocusChange и не хотел пробовать таймер.Таймер слишком опасен для вкуса из-за всех потоков и слишком непредсказуем, поскольку вы не знаете, когда выполняется код.

OnEditorAction не перехватывает, когда пользователь уходит без использования кнопки и еслипожалуйста, обратите внимание, что KeyEvent может быть нулевым.Фокус ненадежен на обоих концах, пользователь может получить фокус и оставить без ввода текста или выбора поля, и пользователю не нужно оставлять последнее поле EditText.

Мое решение использует onFocusChange и флаг, установленный, когдапользователь начинает редактировать текст и функцию для получения текста из последнего сфокусированного представления, которое я вызываю при необходимости.

Я просто очищаю фокус на всех моих текстовых полях, чтобы обмануть код представления оставленного текста, ClearFocusкод выполняется только в том случае, если поле имеет фокус.Я вызываю функцию в onSaveInstanceState, поэтому мне не нужно сохранять флаг (mEditing) в качестве состояния представления EditText и при нажатии важных кнопок и при закрытии действия.

Будьте осторожны с TexWatcher, так как он часто вызывается. Я использую условие для фокуса, чтобы не реагировать, когда код onRestoreInstanceState вводит текст.Я

final EditText mEditTextView = (EditText) getView();

    mEditTextView.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) {
            if (!mEditing && mEditTextView.hasFocus()) {
                mEditing = true;
            }
        }
    });
    mEditTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus && mEditing) {
                mEditing = false;
                ///Do the thing
            }
        }
    });
protected void saveLastOpenField(){
    for (EditText view:getFields()){
            view.clearFocus();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...