Back button action when the keyboard is active

I'm trying to use the back button action to pop up a menu in my application, with the onKeyUp method. As soon as the back key was clicked, the menu should immediately appear.

In my application I work with tabHost, are 3 screens, in the first two there is normal menu, in the third is a search screen, and when I go to it, the keyboard automatically goes up, and the menu some, because at this time it is unnecessary.

My difficulty is being in show this menu again after the back button is clicked, it works in a way, but only appears on the second click of the back button. That is, the first click serves only to download the keyboard, and the second that appears the menu. But I want the first click to download the keyboard and the menu appears, and I'm not getting it. Follow the methods, all in MainActivity.

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {

    if (event != null && KeyEvent.KEYCODE_BACK == event.getKeyCode() || keyCode == KeyEvent.KEYCODE_BACK) {
        Log.i("BOTAO VOLTAR", "BOTÃO VOLTAR CLICADO!!!");
        hideShowTabs(false);
    }
    return false;
}

public void hideShowTabs(boolean option) {

        if (option)
            tabHost.getTabWidget().setVisibility(View.GONE);
        else
            tabHost.getTabWidget().setVisibility(View.VISIBLE);
}

Can someone tell me why it doesn't work on the first click ?? How would you make it work ?? I have two options to do: identify when the keyboard is downloaded, or when the back key is clicked, to bring up the menu. I accept suggestions, since jpa thank you.

Author: ramaral, 2016-02-23

1 answers

This is possible, but unfortunately the Android SDK does not offer a simple way to solve this issue. before trying to implement the solution I would recommend thinking hard about whether you will actually need to intercept the onBackPressed() when the keyboard is present.

My answer is based on this enlightening contribution

  1. create a custom version of View where you need to retrieve onKeyPressed
  2. subscribe dispatchKeyEventPreIme(KeyEvent event)
  3. process the event your way. In the snipped below I chose to process the event on the subscribed object and return a result for the custom View to proceed or not with its default actions.
  4. create an interface to receive the event onBackPressed in view
  5. enter your activity (or other object) to receive the event

OBS 1 - you will need to understand the minimum about creating custom views.

OBS 2 - I found the question interesting and intend to make a tutorial on the subject in more detail. I should do that later this week. Then put the link HERE.

OBS 3 - you can check on my GitHub the full implementation

;

 */ Registre o callback para receber o evento
 */
public void setListener(BackPressed callback){
    mCallback = callback;
}

/**
 * Subscreva o evento <code>dispatchKeyEventPreIme</code>.
 * Intercepte o tipo de evento <code>KeyEvent.KEYCODE_BACK</code>
 * e faça o que quiser com ele.
 */
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
    Log.d(TAG, "dispatchKeyEventPreIme(" + event + ")");
    if ( mCallback != null ) {
        // O View verifica o tipo de evento
        // dá a oportunidade do objeto inscrito
        // processar o evento e anula a ação padrão
        // em caso de retorno positivo
        if ( event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            KeyEvent.DispatcherState state = getKeyDispatcherState();
            if (state != null) {
                if (event.getAction() == KeyEvent.ACTION_DOWN
                        && event.getRepeatCount() == 0) {
                    state.startTracking(event, this);
                    Log.i(TAG, "KeyEvent.ACTION_DOWN");
                    return true;
                } else if (event.getAction() == KeyEvent.ACTION_UP
                        && !event.isCanceled() && state.isTracking(event)) {
                    if ( mCallback.editTextOnBackPressed() ) {
                        Log.i(TAG, "KeyEvent.ACTION_UP | cancelando processo padrão");
                        return true;
                    } else {
                        Log.i(TAG, "KeyEvent.ACTION_UP | processando o processo padrão");
                        return super.dispatchKeyEventPreIme(event);
                    }
                }
            }
        }
    }
    Log.i(TAG, "Returning generic onBackPressed");
    return super.dispatchKeyEventPreIme(event);
}


public interface BackPressed {
    /**
     * Listener para eventos onBackPressed com o teclado presente.
     * O objeto inscrito tem a oportunidade de processar o evento
     * e definir se o <code>View</code> deve seguir ou não com sua
     * ação padrao.
     * @return  true: <code>View</code> abandona a ação padrão e executa
     *                  somente o bloco definido antes do retorno
     *          false: <code>View</code> executa o código definido antes do
     *                  retorno e dá sequência a ação convencional
     */
    boolean editTextOnBackPressed();
}
 0
Author: Tin Megali, 2017-05-23 12:37:27