AdjustResize con animación
He utilizado android: windowSoftInputMode = "adjustResize" en el manifiesto para evitar que el teclado oculte el botón de actividad. Funciona, pero cuando el teclado se abre, mi botón se mueve hacia arriba. Es un poco nervioso, quería saber – ¿puedo tener alguna animación para que la transición sin problemas?
<activity android:name=".Activity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"> </activity>
- Android KeyBoard.Key desactivar iconPreview de claves especiales?
- Salida de un carácter por dos teclas en el teclado de Android
- Problemas con el teclado virtual
- Cómo ocultar el teclado predeterminado de ListViewAdapter en android
- Android ViewPager muestra el teclado virtual en el lugar equivocado
- ¿Por qué no android: windowSoftInputMode = "stateVisible | adjustResize" ajustar la pantalla cuando se muestra el teclado virtual?
- Android: AutoCompleteTextView ocultar teclado virtual
- Android Implementa dos fragmentos que tienen un comportamiento diferente cuando aparece el teclado
- Detectar el botón de búsqueda del teclado
- EditText en ListView pierde foco cuando se presiona en Android 4.x
- Desarrollo de Android: atajo de gancho en el teclado cuando se centra la actividad de la aplicación de teléfono
- Android: quitar Enter Key de softkeyboard
- ListView - mantiene el elemento específico en la vista cuando aparece el teclado virtual
El método setSoftInputMode(int)
no puede ser anulado, su implementación está dentro de la clase Window
y no creo que sea posible reemplazar la ventana actual por la suya. No se puede administrar esto desde WindowManager
también.
Podría crear un listener en un ViewGroup
y captar el diseño de la modificación cuando el SoftKeyboard
está abriendo y cerrando. De hecho, cuando aparece el SKB, el diseño del contenedor se vuelve a dibujar y cambia su altura. A partir de este evento, usted podría manejar para establecer una Animation
en vistas niño y hacer un efecto suave.
Edit: La solución utilizando un GlobalLayoutListener
en la vista de root también es posible en lugar de (la solución presentada a continuación 🙂 la creación de una clase de grupo de vista personalizado.
Debe crear su propio grupo de vistas y convertirlo en un contenedor principal en el diseño. Implementará una interfaz que se manejará en la clase de interfaz de usuario ( Activity
, Fragment
, lo que sea). Encontré este blog para detectar los eventos en SKB para (~) todas las versiones . Según él, aquí está la clase del viewgroup para manejar los cambios de la altura:
public class ContainerViewHandler extends RelativeLayout { private boolean isKeyboardShown; private onKeyboardStateChange listener; public ContainerViewHandler(Context context) { super(context); } public ContainerViewHandler(Context context, AttributeSet attrs) { super(context, attrs); } public ContainerViewHandler(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setKeyboardStateListener(onKeyboardStateChange listener) { this.listener = listener; } // Callbacks public interface onKeyboardStateChange { void onKeyboardShow(); void onKeyboardHide(); } @Override public boolean dispatchKeyEventPreIme(@NonNull KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { // Keyboard is hiding if (isKeyboardShown) { isKeyboardShown = false; listener.onKeyboardHide(); } } return super.dispatchKeyEventPreIme(event); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec); final int actualHeight = getHeight(); if (actualHeight > proposedHeight) { // Keyboard is showing if (!isKeyboardShown) { isKeyboardShown = true; listener.onKeyboardShow(); } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
Ahora, debe agregar este grupo de vistas en el diseño (por ejemplo, <com.package.name.ContainerViewHandler .../>
). A continuación, debe implementar la interfaz setKeyboardStateListener
anterior en la actividad, como la siguiente:
ContainerViewHandler containerView = (ContainerViewHandler) findViewById(R.id.container_view); containerView.setKeyboardStateListener(new ContainerHandler.onKeyboardStateChange() { @Override public void onKeyboardShow() { Log.v("onKeyboardShow()", "SoftKeyboard is showing. Hello!"); } @Override public void onKeyboardHide() { Log.v("onKeyboardHide()", "SoftKeyboard is hiding, Bye bye!"); } });
Por lo tanto, puede manejar diferentes animaciones para manejar y evitar que el botón "saltar" directamente por encima de la SKB. Para probar esto, intento reproducir un efecto de rebote:
Así se ve mi implementación:
containerView.setKeyboardStateListener(new ContainerViewHandler.onKeyboardStateChange() { @Override public void onKeyboardShow() { setAnimationUp(); } @Override public void onKeyboardHide() { setAnimationDown(); } }); private void setAnimationUp() { footerButton.setVisibility(View.GONE); float dpY = AppUtils.convertPxToDp(20, this); // custom conversion method Animation a1 = new TranslateAnimation(0, 0, footerButton.getHeight() * 4, -(dpY)); a1.setDuration(250); a1.setFillAfter(true); final Animation a2 = new TranslateAnimation(0, 0, -(dpY), 0); a2.setDuration(320); a2.setFillAfter(true); a1.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { footerButton.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { footerButton.startAnimation(a2); } @Override public void onAnimationRepeat(Animation animation) { } }); footerButton.startAnimation(a1); } private void setAnimationDown() { float dpY = AppUtils.convertPxToDp(30, this); // custom conversion method Animation b1 = new TranslateAnimation(0, 0, -(dpY), dpY); b1.setDuration(300); b1.setFillAfter(true); final Animation b2 = new TranslateAnimation(0, 0, dpY, 0); b2.setDuration(320); b2.setFillAfter(true); b1.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { footerButton.startAnimation(b2); } @Override public void onAnimationRepeat(Animation animation) { } }); footerButton.startAnimation(b1); }
Comienzo configurando dos animaciones (a1, a2) en la primera devolución de llamada:
- A1 : comienza por debajo (detrás) de la SKB (alrededor de
4xbutton's height
) y hasta20dp
encima de ella, -
20dp
: comienza en20dp
y vuelve a0dp
(posición normal).
Y otros dos (b1, b2) en la segunda devolución de llamada:
- B1 : comienza donde el botón está hasta
30dp
en la parte superior y baja a30dp
fuera del contenedor padre, - B2: finalmente, de
30dp
a0dp
(la posición inicial).
PS: no se olvide de usar adjustResize
en el manifiesto y hacer que el contenido (por ejemplo, edittexts en mis pruebas) above
el botón de pie de página que tiene alignParentBottom
a true.
- ¿Cómo determinar de forma fiable el ancho de una cadena de varias líneas?
- Problema de alineación de texto al utilizar fuente árabe