EditText не вызывает изменения при нажатии назад - PullRequest
1 голос
/ 03 августа 2011

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

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

Ответы [ 5 ]

3 голосов
/ 18 августа 2011

У меня была такая же проблема в приложении, которое я написал некоторое время назад.Сейчас оно прекращено, но это не ваш вопрос 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 добавляет слушателя, который будетвызывается каждый раз, когда компоновка высоты изменяется как минимум на 128 пикселей.Это хитрость, и она не будет работать с клавиатурами, размер которых меньше 128 пикселей (но я думаю, что каждая клавиатура имеет такую ​​высоту). Если LayoutHeight изменился, вы получите уведомление, отображается ли он сейчас или нет.

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

1 голос
/ 29 декабря 2017

Это измененная версия ответа @ mikepenz, поскольку она не работает на Android 8 в режиме windowSoftInputMode = "AdjustPan" .

Язык котлин . Используйте это представление в качестве корневого представления и установите keyboardListener:

class KeyboardAwareConstraintLayout(context: Context?, attrs: AttributeSet?) : ConstraintLayout(context, attrs)
{

  var keyboardListener: KeyboardListener? = null

  constructor(context: Context?) : this(context, null)


  override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
  {
    val rect = Rect()
    getWindowVisibleDisplayFrame(rect)
    val statusBarHeight = rect.top
    val keyboardHeight = rootView.height - (rect.bottom - rect.top) - statusBarHeight
    // R.dimen.keyboard_min_height has set to 120dp, 
    // as a reasonable minimum height of a soft keyboard
    val minKeyboardHeight = resources.getDimensionPixelSize(R.dimen.keyboard_min_height)

    keyboardListener?.onKeyboardShown(keyboardHeight > minKeyboardHeight)

    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
  }
}

interface KeyboardListener
{
  fun onKeyboardShown (shown: Boolean)
}
0 голосов
/ 21 августа 2016

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

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;
    }
});
0 голосов
/ 03 августа 2011

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

((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;
    }
})
0 голосов
/ 03 августа 2011

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

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