stackoverflow - system input method android virus
android: windowSoftInputMode="adjustResize" no hace ninguna diferencia? (10)
Tengo un diálogo falso que usa este diseño:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/containerPageConatiner">
<FrameLayout android:id="@+id/dialogHolder"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="15dp"
android:layout_gravity="center"
android:background="@drawable/panel_picture_frame_bg_focus_blue"/>
</FrameLayout>
<FrameLayout>
un fragmento dentro de <FrameLayout>
dependiendo del diálogo que se está abriendo: la actividad que controla el Diálogo se ve así:
<activity
android:label="@string/app_name"
android:name=".activity.DialogActivity"
android:theme="@style/CustomTheme.Screen.Transparent"
android:windowSoftInputMode="adjustResize">
Lamentablemente, al hacer clic en un texto de edición dentro del cuadro de diálogo, no se cambia el tamaño. El windowSoftInputMode
literalmente no hace diferencia ya que la funcionalidad es la misma que el modo pan.
Documentation dice "Esto, por supuesto, solo funciona para aplicaciones que tienen un área reajustable que se puede reducir para hacer suficiente espacio", pero no dice lo que significa "un área redimensionable" y me hace pensar que de alguna manera no lo hago ¿ Tiene un área reajustable?
Si alguien sabe qué pasa, ¿pueden ayudarme?
EDITAR
Rodear el diálogo como así no cambia nada:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/containerPageConatiner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/dialogHolder"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="15dp"
android:layout_gravity="center"
android:background="@drawable/panel_picture_frame_bg_focus_blue"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
EDIT2
Scrollview como padre tampoco ayuda:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/containerPageConatiner"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/dialogHolder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="15dp" />
</ScrollView>
Asegúrese de establecer windowTranslucentStatus
en false
en sus estilos.
Como se descubrió el póster original cuando se asigna el Flag de pantalla completa a una actividad, el atributo android: windowFullscreen no funcionará y, por lo tanto, su ventana no cambiará de tamaño cuando el teclado virtual sea visible y no se pueda desplazar.
Simplemente eliminar el indicador de Pantalla completa y no usar un tema de Pantalla completa permitirá desplazarse cuando el teclado virtual esté visible.
Creé un nuevo proyecto para tratar de obtener las funciones básicas que funcionan para el cambio de tamaño de la ventana y lo moví lentamente hacia el objetivo de mi proyecto. Al hacer esto rastreé el problema hasta esto:
En mi jerarquía de tema tenía esta propiedad:
<item name="android:windowFullscreen">true</item>
que fue enterrado en el nivel de Theme.Black.NoTitleBar.FullScreen
- Ancestro de mi tema personalizado.
La documentation sugiere que esta es una "Bandera que indica si esta ventana debe llenar toda la pantalla". Eso suena como algo bueno si tienes una aplicación que ocupa toda la pantalla ... Excepto que todavía ocupa toda la pantalla sin la bandera.
De hecho, una vez que hayas sacado esto, no hay absolutamente ningún cambio en la aplicación ... aparte de adjustResize
ahora funciona perfectamente.
Hace un tiempo también tuve el mismo problema en una biblioteca que he creado. ( MaterialDrawer )
Por lo que puedo ver, todas las respuestas proporcionadas no resuelven el problema principal, solo apuntan a eliminar el indicador de pantalla completa ( android:windowFullscreen
), que no es una solución para muchos por ahí.
El "problema" mencionado anteriormente solo aparece en las versiones de Android que comienzan con el Nivel 19 de API (KITKAT), porque cambiaron el comportamiento. Para ser correcto, no hay problema, está funcionando como estaba previsto. Vea el comentario de un empleado de Android-Issue ( Android-Issue ).
Así que empecé a buscar en la fuente de Android y ViewTreeObserver.OnGlobalLayoutListener
la siguiente solución usando ViewTreeObserver.OnGlobalLayoutListener
y reaccioné si el teclado se mostraba u ocultaba. Si se muestra el teclado, agrego el relleno en la parte inferior de la vista del contenedor, que emulará lo mismo que lo adjustResize
el adjustResize
.
Solución
Para simplificar el uso lo he envuelto todo en una clase simple de ayuda KeyboardUtil.
/**
* Created by mikepenz on 14.03.15.
* This class implements a hack to change the layout padding on bottom if the keyboard is shown
* to allow long lists with editTextViews
* Basic idea for this solution found here: http://.com/a/9108219/325479
*/
public class KeyboardUtil {
private View decorView;
private View contentView;
public KeyboardUtil(Activity act, View contentView) {
this.decorView = act.getWindow().getDecorView();
this.contentView = contentView;
//only required on newer android versions. it was working on API level 19 (Build.VERSION_CODES.KITKAT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
public void enable() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
public void disable() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
//a small helper to allow showing the editText focus
ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
decorView.getWindowVisibleDisplayFrame(r);
//get screen height and calculate the difference with the useable area from the r
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int diff = height - r.bottom;
//if it could be a keyboard add the padding to the view
if (diff != 0) {
// if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
//check if the padding is 0 (if yes set the padding for the keyboard)
if (contentView.getPaddingBottom() != diff) {
//set the padding of the contentView for the keyboard
contentView.setPadding(0, 0, 0, diff);
}
} else {
//check if the padding is != 0 (if yes reset the padding)
if (contentView.getPaddingBottom() != 0) {
//reset the padding of the contentView
contentView.setPadding(0, 0, 0, 0);
}
}
}
};
/**
* Helper to hide the keyboard
*
* @param act
*/
public static void hideKeyboard(Activity act) {
if (act != null && act.getCurrentFocus() != null) {
InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
}
}
}
Luego puede usarlo en su actividad o fragmento haciendo lo siguiente:
//initialize the KeyboardUtil (you can do this global)
KeyboardUtil keyboardUtil = new KeyboardUtil(activity, getContent().getChildAt(0));
//enable it
keyboardUtil.enable();
//disable it
keyboardUtil.disable();
La clase util completa se utiliza en la biblioteca MaterialDrawer mencionada anteriormente y se puede encontrar aquí KeyboardUtil . Esto siempre contendrá la última versión. (si hay mejoras)
He tenido que establecer
<item name="android:windowFullscreen">false</item>
A pesar de eso, nunca lo configuré como verdad y la aplicación en realidad no era de pantalla completa.
Intenta poner tu LinearLayout
en un ScrollView
, que funcionó para mí una vez ...
No sé por qué, pero si tiene <item name="android:windowTranslucentNavigation">true</item>
en su tema, cámbielo a false
. Y comenzará a funcionar. Muy extraño.
Parece que el problema es con FrameLayout, ya que se comporta de esa manera, que cada niño ocupa el espacio visible de ese marco, por lo tanto, no es necesario cambiar el tamaño para adaptarse a los niños. Intenta usar RelativeLayout. Deberia de funcionar.
Puede ajustar la reducción de tamaño mediante programación. Agregue esto en onCreate () de su actividad.
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Sin usar ScrollView
como mi padre, acabo de agregar android:fitsSystemWindows="true"
a mi vista principal (que era RelativeLayout
y adjustResize
al Manifiesto de la actividad y funcionó).