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.