Надежный способ узнать, когда Android-софт клавиатура уходит в отставку (обратный вызов, который работает на каждом телефоне) - PullRequest
24 голосов
/ 09 мая 2011

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

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

Проблема в том, что мы не получаем фиксированное событие, поскольку разные телефоны имеют разные клавиатуры.В некоторых есть кнопка «Готово», а в наших телефонах HTC есть кнопки «Ввод».Мы попытались использовать imeOptions как «готово», но это не повлияло на телефоны HTC.

Мы также знаем, что клавиатура может быть отклонена нажатием кнопки назад .Поэтому мой вопрос заключается в том, есть ли надежный способ узнать, когда пользователь прекратил ввод или когда клавиатура скрыта, точно так же, как обратный вызов textFieldShouldReturn в iphone sdk (который всегда срабатывает, когда клавиатура выключается, независимо откакая клавиша заставила его выйти из строя) ..

Другими словами, как разработчик Android обрабатывает программную клавиатуру? Я проверяю KeyEvent.KEYCODE_ENTER на editText onClick () и выполняйте мои задачи там. Он работает на моем HTC Android, но не на телефоне Nexus моих друзей, в котором вместо кнопки ввода есть кнопка «Готово».Там onClick даже не называется.Как разработчик справляется с этим?

РЕДАКТИРОВАТЬ: После потери половины моих волос, и с помощью некоторых хороших друзей здесь

У меня естьперепробовал все ваши предложения, но в конце с помощью onEditorActionListener вместе с методом onKeyListener сделали свое дело.В обратном вызове onEdit для onEditorActionListener я проверил наличие ключевого кода ACTION_DONE , который вызывался на клавиатурах с кнопкой done. На клавиатурах, на которых есть вход, вызывается onKey.В методе onKey я также проверил для KEYCODE_BACK , так что событие аппаратного обратного нажатия также может быть обработано.Я еще не обнаружил устройство Android с готовым и войти на клавиатуре (серьезно), тем не менее, я даже обрабатывал этот случай с флагом.Спасибо @Femi за предложение onEditorActionListener, и спасибо всем друзьям за вашу помощь.Но ответ на мой первоначальный вопрос

Q: Есть ли надежный и простой способ узнать, как Android софт-клавиатура уходит в отставку (обратный вызов, который работает на каждом телефоне)

Ответ: Нет, все методы, предложенные здесь, и все методы, предложенные на других сайтах, не просты.И я думаю, что обработка события для клавиши возврата с клавиатуры - самая простая вещь для любой операционной системы. Гугл, ты там?

Ответы [ 7 ]

7 голосов
/ 09 мая 2011

Так как кажется, что вы перехватываете событие KEYCODE_ENTER , вы можете использовать это: http://developer.android.com/reference/android/widget/TextView.html#setOnEditorActionListener%28android.widget.TextView.OnEditorActionListener%29. Теоретически это позволит вам определить, каким является конечное действие метода ввода ( обратно, готово, введите или что-то еще) и ответьте на него.

Дайте мне знать, если это работает для вас.

2 голосов
/ 23 мая 2011

Разве вам не нужно выполнять эти вычисления, когда пользователь покидает TextView на аппаратной клавиатуре? Я бы сосредоточился не на клавиатуре, а на самом TextView. Если это так, то, что вы, вероятно, хотите, это setTransformationMethod

Вы должны будете реализовать пользовательский TransformationMethod , в частности, метод getTransformation, который преобразует исходный CharSequence в другой. Затем вы можете использовать onFocusChanged, чтобы применить это, только когда фокус потерян для этого TextView.

1 голос
/ 23 мая 2011

Вы пытались реализовать пользовательское представление EditText, где вы переопределяете dispatchKeyEventPreIme? Как и в ответе, опубликованном Арно (ссылка Перехватить кнопку возврата с программной клавиатуры ), но вместо использования пользовательского макета используйте пользовательский EditText и переопределите:

@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
    if(KeyEvent.KEYCODE_BACK == event.getKeyCode()) {
       //this hides soft keyboard in super.dispatchKeyEventPreIme(event)
    }
    return super.dispatchKeyEventPreIme(event);
}

Я предложил это решение в этот вопрос

1 голос
/ 22 мая 2011

Я нашел решение на этой SO странице: Кнопка возврата на программную клавиатуру

Ответ от mhradek имеет 0 голосов, но, похоже, он работает.

Идея состоит в том, чтобы расширить базовый макет вашей активности, чтобы вы могли переопределить метод dispatchKeyEventPreIme и делать то, что вы хотите, относительно переданного KeyEvent. Обратите внимание, что вы несете ответственность за управление программной клавиатурой.

Я использую его и могу определенно перехватывать нажатия клавиш (например, кнопку «назад»), не используя «мягкую» клавиатуру. Мне еще предстоит поиграть с ним, чтобы увидеть, что возможно, а что нет.

Надеюсь, это поможет.

1 голос
/ 19 мая 2011

Не могу поверить, что в этом случае у Google нет независимого обратного вызова с клавиатуры

Ух, я не могу поверить, что ни то, ни другое. У меня сейчас похожая проблема. В дополнение к IME ACTION я проверяю изменения фокуса на EditFields. Это нормально в большинстве случаев, но не всегда будет работать.

Я нашел способ получать уведомления, когда клавиатура скрыта, но это еще не полное решение (и я не уверен, хорошая ли это идея), но у меня нет времени, чтобы продолжить прямо сейчас вот я и подумал, что смогу бросить начало идеи здесь ...:

Введите свой собственный EditText (расширить EditText) и переопределить onCreateInputConnection. В вашей onCreateInputConnection верните собственную реализацию InputConnection (вы можете просто расширить BasicInputConnection. Метод «FinineComposingText ()» InputConnections всегда вызывается, когда клавиатура скрыта (также когда пользователь нажимает клавишу «назад»).

Это код, и, возможно, у кого-то есть идея, почему введенный текст не отображается в этом поле редактирования; -)

public class MyEditText extends EditText{

public MyEditText(Context context) {
    super(context);
}

public MyEditText(Context context, AttributeSet attrs) {
    super(context);
}

public MyEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    System.out.println("onCreateInputConnection, "+outAttrs.actionId);
    return new MyInputConnection(this,true);
}

private class MyInputConnection extends BaseInputConnection{

    public MyInputConnection(View targetView, boolean fullEditor) {
        super(targetView, fullEditor);
    }

    @Override
    public boolean finishComposingText() {
        System.out.println("FINISH");
        return super.finishComposingText();
    }   
}
 }

JPM

0 голосов
/ 12 октября 2011

Этот код отлично работает у меня с HTC и клавиатурой Android по умолчанию:

editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                // handle enter key on keyboard
                if (actionId == EditorInfo.IME_ACTION_SEND || 
                        (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN)) {
                    if (uid != null) {
                        // hide keyboard
                        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                        // perform other stuff

                        return true;
                    }
                }
                return false;
            }
        });

Используя следующее в XML-файле editText:

android:imeOptions="actionSend"

Конечно, вы также можете использовать что-то еще, например, send, просто убедитесь, что изменили это и в коде XML, и в Java.

0 голосов
/ 08 июля 2011

Я не пробовал это, но, читая документацию, кажется возможным.

//    From an activity, you can call

if (getResources().getConfiguration().keyboardHidden == Configuration.KEYBOARDHIDDEN_YES) {
// your code here
}
...