EditText не вызывает изменения при нажатии

В приложении с корзиной покупок я предоставляю возможность изменять количество элементов через EditText, который позволяет использовать только числовой ввод.
Все работает отлично, за исключением случаев, когда пользователь меняет поле, а затем нажимает кнопку "Назад", чтобы скрыть мягкую клавиатуру. В этом случае поле показывает измененное значение, но я не знаю, как я могу обнаружить это изменение и отреагировать на него. Ожидание перехода на другое действие не является вариантом.
Когда пользователь подтвердит кнопкой "done", я могу обработать это с помощью "OnEditorActionListener". Но как насчет задней клавиши?

обновление:
Как оказалось, ни onKeyDown/onBackPressed, ни OnKeyListener в поле редактирования не запускаются при закрытии мягкой клавиатуры с помощью обратного ключа.

Ответ 1

У меня была та же проблема в приложении, которое я написал некоторое время назад. Сейчас это противоречит, но это не ваш вопрос xD.

Фактически нет возможности отслеживать такую ​​операцию, но я нашел отличное (более или менее) решение для добавления такой функциональности. Это довольно просто в теории, но это тоже "взломать".

Итак, вам понадобится пользовательский линейный макет, содержащий ваше приложение или специальный регион. После этого вы должны добавить его слушателем. И это будет работать только в портретном режиме.

Итак, вот код: (извините, но я не могу вспомнить источник)

Пользовательский макет:

LinearLayoutThatDetactsSoftwarekeyboard.java (что оригинальное имя макета xD)

package com.tundem.people.Layout;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/*
 * LinearLayoutThatDetectsSoftKeyboard - a variant of LinearLayout that can detect when 
 * the soft keyboard is shown and hidden (something Android can't tell you, weirdly). 
 */

public class LinearLayoutThatDetectSoftkeyboard extends LinearLayout {

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

    public interface Listener {
        public void onSoftKeyboardShown(boolean isShowing);
    }

    private Listener listener;

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity) getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff > 128); // assume all soft
                                                        // keyboards are at
                                                        // least 128 pixels high
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

И как вы добавляете слушателя:

final LinearLayoutThatDetectSoftkeyboard lltodetectsoftkeyboard = (LinearLayoutThatDetectSoftkeyboard) findViewById(R.id.LinearLayout_SoftKeyboard);
    lltodetectsoftkeyboard.setListener(new Listener() {

        public void onSoftKeyboardShown(boolean isShowing) {
            if (actMode == MODE_SMS && isShowing) {
                findViewById(R.id.LinearLayout_bottomnavigationbar).setVisibility(View.GONE);
            } else {
                findViewById(R.id.LinearLayout_bottomnavigationbar).setVisibility(View.VISIBLE);
            }
        }
    });

LinearLayout добавляет прослушиватель, который будет вызываться каждый раз, когда изменение layoutheight изменяется не менее чем на 128 пикселей. Это трюк, и он не будет работать с клавиатурами, размер которых меньше 128 пикселей (но я думаю, что каждая клавиатура имеет такую ​​высоту) Если LayoutHeight изменился, вы получите уведомление, если оно показывается сейчас или нет.

Надеюсь, мой ответ был полезен. Возможно, вы снова найдете настоящий источник на StackOverFlow. Я не буду красть кого-то гения. Кредиты передаются неизвестному лицу;)

Ответ 2

Вы можете переопределить onBackPressed в своей активности (псевдокод - быть предупрежденным):

@Override
public void onBackPressed() {
    if(userHasChangedAnything) {
        revertChanges();
    } else {
        super.onBackPressed();
    }
}

Ответ 3

С новой информацией о коде, находящемся в фрагменте, я бы предложил добавить в текстовое поле прослушиватель клавиш. Этот код не был протестирован, но должен работать.

((EditText) findViewById(R.id.button)).setOnKeyListener(new OnKeyListener() { 
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
         if ((keyCode == KeyEvent.KEYCODE_BACK)) {
              Log.d(this.getClass().getName(), "back button pressed");
              return true;
         }
         return false;
    }
})

Ответ 4

Извините меня, если это не актуально, но у меня была эта проблема, и я забыл, что добавил OnKeyListener, который заставил вернуться назад к моему диалоговому фрагменту. Я переписал слушателя следующим образом. Для решения проблемы было добавлено условие "Верх".

getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
        if(keyEvent.getKeyCode() == KeyEvent.KEYCODE_DEL) {
            return false;
        }
        if(keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            if(iYoutubePickerDialog != null) {
                iYoutubePickerDialog.closeYoutubeDialog(getDialog());
            }
        }
        return true;
    }
});