Saltar al contenido

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

Posterior a observar en diferentes repositorios y sitios webs finalmente encontramos la solución que te enseñamos aquí.

Solución:

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 puede escuchar la animación de mostrar/ocultar el teclado y hacer 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 ha sido puesto a disposición en un Compat versión, por lo que debe recurrir a hacks.

Puede obtener las inserciones de la ventana y si las inserciones inferiores son más grandes que algún valor que considere razonablemente bueno (por experimentación), puede considerar que muestra el teclado. Esto no es excelente y puede fallar en algunos casos, pero no hay soporte de marco para eso.

Esta es una buena respuesta sobre esta pregunta exacta https://stackoverflow.com/a/36259261/372076. Alternativamente, aquí hay una página que brinda 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 suaves y
onConfigurationChanged no se llamará para teclados suaves (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.

Esta puede no ser la solución más efectiva. Pero esto funcionó para mí cada vez… Llamo a esta función donde sea que necesite escuchar el teclado suave.

boolean isOpened = false;

public void setListenerToRootView() 
    final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
        @Override
        public void onGlobalLayout() 

            int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
            if (heightDiff > 100)  // 99% of the time the height diff will be due to a keyboard.
                Toast.makeText(getApplicationContext(), "Gotcha!!! softKeyboardup", 0).show();

                if (isOpened == false) 
                    //Do two things, make the view top visible and the editText smaller
                
                isOpened = true;
             else if (isOpened == true) 
                Toast.makeText(getApplicationContext(), "softkeyborad Down!!!", 0).show();
                isOpened = false;
            
        
    );

Nota: este enfoque causará problemas si el usuario usa un teclado flotante.

lo hice de esta manera:

Agregar OnKeyboardVisibilityListener interfaz.

public interface OnKeyboardVisibilityListener 
    void onVisibilityChanged(boolean visible);

HomeActivity.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.

Calificaciones y comentarios

Si te mola el proyecto, tienes la libertad de dejar un post acerca de qué te ha impresionado de esta crónica.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *