¿Cómo capturar el evento "mostrar/ocultar teclado virtual" en Android?
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!
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 Compat
versió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
onConfigurationChanged
no 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.
Lo hice de esta manera:
Agregar OnKeyboardVisibilityListener
interfaz.
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.