¿Cómo capturar el evento "mostrar/ocultar teclado virtual" en Android?

Resuelto Sander Versluys asked hace 54 años • 21 respuestas

Me gustaría modificar el diseño en función de si se muestra o no el teclado virtual. He buscado en la API y en varios blogs, pero parece que no encuentro nada útil.

¿Es posible?

¡Gracias!

Sander Versluys avatar Jan 01 '70 08:01 Sander Versluys
Aceptado

Actualización 2020

Esto ahora es posible:

En Android 11, puedes hacer

view.setWindowInsetsAnimationCallback(object : WindowInsetsAnimation.Callback {
    override fun onEnd(animation: WindowInsetsAnimation) {
        super.onEnd(animation)
        val showingKeyboard = view.rootWindowInsets.isVisible(WindowInsets.Type.ime())
        // now use the boolean for something
    }
})

También puedes escuchar la animación de mostrar/ocultar el teclado y realizar la transición correspondiente.

Recomiendo leer la vista previa de Android 11 y la documentación correspondiente.

Antes de Android 11

Sin embargo, este trabajo no está disponible en una Compatversión, por lo que es necesario recurrir a hacks.

Puede obtener los recuadros de la ventana y, si los recuadros inferiores son más grandes que algún valor que considere razonablemente bueno (mediante experimentación), puede considerar que se muestra el teclado. Esto no es muy bueno y puede fallar en algunos casos, pero no existe un marco de soporte para eso.

Esta es una buena respuesta a esta pregunta exacta https://stackoverflow.com/a/36259261/372076 . Alternativamente, aquí hay una página que ofrece algunos enfoques diferentes para lograr esto antes de Android 11:

https://developer.salesforce.com/docs/atlas.en-us.noversion.service_sdk_android.meta/service_sdk_android/android_detecting_keyboard.htm


Nota

Esta solución no funcionará para teclados virtuales y onConfigurationChangedno se utilizará para teclados virtuales (virtuales).


Tienes que manejar los cambios de configuración tú mismo.

http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange

Muestra:

// from the link above
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    
    // Checks whether a hardware keyboard is available
    if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
        Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
    } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
    }
}

Luego simplemente cambie la visibilidad de algunas vistas, actualice un campo y cambie su archivo de diseño.

Pedro Loureiro avatar Dec 06 '2010 10:12 Pedro Loureiro

Lo hice de esta manera:

Agregar OnKeyboardVisibilityListenerinterfaz.

public interface OnKeyboardVisibilityListener {
    void onVisibilityChanged(boolean visible);
}

InicioActividad.java :

public class HomeActivity extends Activity implements OnKeyboardVisibilityListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_up);
    // Other stuff...
    setKeyboardVisibilityListener(this);
}

private void setKeyboardVisibilityListener(final OnKeyboardVisibilityListener onKeyboardVisibilityListener) {
    final View parentView = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
    parentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        private boolean alreadyOpen;
        private final int defaultKeyboardHeightDP = 100;
        private final int EstimatedKeyboardDP = defaultKeyboardHeightDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
        private final Rect rect = new Rect();

        @Override
        public void onGlobalLayout() {
            int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, parentView.getResources().getDisplayMetrics());
            parentView.getWindowVisibleDisplayFrame(rect);
            int heightDiff = parentView.getRootView().getHeight() - (rect.bottom - rect.top);
            boolean isShown = heightDiff >= estimatedKeyboardHeight;

            if (isShown == alreadyOpen) {
                Log.i("Keyboard state", "Ignoring global layout change...");
                return;
            }
            alreadyOpen = isShown;
            onKeyboardVisibilityListener.onVisibilityChanged(isShown);
        }
    });
}


@Override
public void onVisibilityChanged(boolean visible) {
    Toast.makeText(HomeActivity.this, visible ? "Keyboard is active" : "Keyboard is Inactive", Toast.LENGTH_SHORT).show();
  }
}

Espero que esto te ayude.

Hiren Patel avatar Mar 28 '2016 09:03 Hiren Patel