studio - ocultar teclado android in fragment
Cuando aparece el teclado virtual, hace que mi campo EditText pierda enfoque (9)
Agregue android: windowSoftInputMode = "adjustResize" en la actividad que contiene la vista de lista o EditText. Esto resolverá su problema.
<activity android:name=".MainActivity"
android:windowSoftInputMode="adjustResize">
</activity>
Tengo algunos campos EditText en un ListView. Cuando toco en uno de los campos EditText, el teclado se desliza a la vista (como debería), pero el campo EditText al que hice tapping pierde el foco. Intenté utilizar varios métodos de InputMethodManager para que el teclado comenzara a verse (para evitar el problema en lugar de resolverlo de verdad), pero eso no funcionó: el teclado no estaba a la vista cuando apareció Activity.
El tipo de EditText es number
, y cuando el teclado se desliza, es un teclado numérico, pero cuando termina de deslizarse y EditText pierde el foco, cambia al teclado alfabético (lo que refuerza la idea de que EditText ya no tiene foco) .
Mis preguntas son estas:
1) ¿Cómo puedo hacer que la selección de mi campo EditText y el deslizamiento posterior del teclado no hagan que EditText pierda el foco?
... fallando en eso...
2) ¿Cómo puedo hacer que el teclado comience a mi vista para que nunca tenga que deslizarse hacia adentro (evitando así el comportamiento que me parece objetable)?
Mi manifiesto incluye android:windowSoftInputMode="stateAlwaysVisible"
, pero el teclado no aparece hasta que toco EditText. Esta omisión del atributo ''stateAlwaysVisible'' parece ocurrir solo en el emulador; en mi dispositivo aprovisionado, se respeta así que la pregunta número 2 anterior funciona en el dispositivo ... pero no en el emulador.
¡Gracias por cualquier ayuda que usted nos pueda proporcionar!
Así es como lo hice. El onFocusChangeListener()
se llama varias veces cuando tocas un EditText
para escribir texto en él. La secuencia es:
- Si el foco estaba en una vista diferente, entonces esa vista pierde el foco
- El objetivo gana enfoque
- El teclado suave aparece.
- Esto causa que el objetivo pierda enfoque
- El código detecta esta situación y llama a target.requestFocus ()
- La vista más a la izquierda, más alta, gana foco, debido a las tonterías de Android
- La vista más a la izquierda pierde el foco, debido a que se llama a requestFocus
El objetivo finalmente gana foco
////////////////////////////////////////////////////////////////// private final int minDelta = 300; // threshold in ms private long focusTime = 0; // time of last touch private View focusTarget = null; View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean hasFocus) { long t = System.currentTimeMillis(); long delta = t - focusTime; if (hasFocus) { // gained focus if (delta > minDelta) { focusTime = t; focusTarget = view; } } else { // lost focus if (delta <= minDelta && view == focusTarget) { focusTarget.post(new Runnable() { // reset focus to target public void run() { focusTarget.requestFocus(); } }); } } } };
El código anterior funciona bien para las ventanas emergentes del teclado. Sin embargo, no detecta la ventana emergente de voz a texto.
Debe probar este código en un dispositivo con el teclado de hardware siempre visible. El comportamiento también puede suceder aquí.
Para evitar esto, puede tener el teclado siempre visible ... pero eso no es muy fácil, como puede ver en este hilo:
https://groups.google.com/forum/#!topic/android-developers/FyENeEdmYC0
En teoría, es posible que tengas que crear tu propio teclado Android (aunque usando como base el teclado original de Android) como se describe aquí: Android: ¿Cómo hacer que el teclado siempre esté visible?
Debes cambiar en tu AndroidManifest.xml
Agregar android: windowSoftInputMode = "adjustPan" en la actividad que contiene la vista de lista. Esto resolverá su problema.
<activity android:name=".MyEditTextInListView"
android:label="@string/app_name"
android:windowSoftInputMode="adjustPan">
Saludos
En AndroidManifest.xml usa adjustNothing en la actividad que contiene las vistas
<activity
android:name=".ActivityName"
android:windowSoftInputMode="adjustNothing">
En mi caso, esto está sucediendo porque cuando ListView cambia el tamaño, vuelve a crear todos los elementos de la lista (es decir, vuelve a llamar a getView () para cada elemento visible de la lista).
Como EditText está dentro del diseño que estoy devolviendo de getView (), esto significa que es una instancia diferente de EditText que la que tenía el foco anteriormente. Una consecuencia secundaria es que cuando el teclado virtual aparece o desaparece, descubro que estaba perdiendo el contenido de EditText.
Como quería que mi vista fuera completamente accesible (es decir, quiero que se redimensione en lugar de esconderla detrás de la ventana del teclado con algunas partes no accesibles), no pude usar la respuesta de Frank, que de lo contrario parece ser el mejor enfoque.
Lo solucioné usando OnFocusChangeListener en EditText para grabar la marca de tiempo cuando se perdió el foco, y luego en getView () al volver a crear el elemento de la lista, si la hora actual está dentro de un umbral desde cuando se perdió el foco, invoque requestFocus ( ) para devolverlo al EditText en cuestión.
También puede tomar el texto de la instancia anterior de EditText en ese punto y transferirlo a la nueva instancia.
private class MyAdapter<Type> extends ArrayAdapter<String>
implements OnFocusChangeListener
{
private EditText mText;
private long mTextLostFocusTimestamp;
private LayoutInflater mLayoutInflater;
public MyAdapter(Context context, int resource, int textResourceId, ArrayList<String> data, LayoutInflater li) {
super(context, resource, textResourceId, data);
mLayoutInflater = li;
mTextLostFocusTimestamp = -1;
}
private void reclaimFocus(View v, long timestamp) {
if (timestamp == -1)
return;
if ((System.currentTimeMillis() - timestamp) < 250)
v.requestFocus();
}
@Override public View getView (int position, View convertView, ViewGroup parent)
{
View v = mLayoutInflater.inflate(R.layout.mylayout, parent, false);
EditText newText = (EditText) v.findViewById(R.id.email);
if (mText != null)
newText.setText(mText.getText());
mText = newText;
mText.setOnFocusChangeListener(this);
reclaimFocus(mText, mTextLostFocusTimestamp);
return v;
}
@Override public void onFocusChange(View v, boolean hasFocus) {
if ((v == mText) && !hasFocus)
mTextLostFocusTimestamp = System.currentTimeMillis();
}
}
Para aquellos que vienen aquí con Xamarin o Xamarin.Formas:
También tuve el mismo problema, pero solo con Android 5.x: todas las versiones más nuevas, incluida la 8.1, funcionaron bien.
Obviamente Sheltond tenía razón al decir:
En mi caso, esto está sucediendo porque cuando ListView cambia el tamaño, vuelve a crear todos los elementos de la lista (es decir, vuelve a llamar a getView () para cada elemento visible de la lista).
Mi vista de lista también estaba cambiando de tamaño y no, la solución de Frank para establecer windowSoftInputMode="adjustPan"
no era una opción para mí porque eso significa que el teclado mueve la vista de lista parcialmente fuera de la pantalla.
Todo lo que tenía que hacer después de horas de depuración de foco era establecer la estrategia de almacenamiento en caché de la célula de la Lista de formularios de Xamarin Forms:
De
CachingStrategy="RecycleElement"
A
CachingStrategy="RetainElement"
Esto evitará que las células se vuelvan a crear. Sin embargo, esto podría dar como resultado un mal rendimiento y un alto consumo de memoria para listas enormes. Ten cuidado
Si editText dentro de listView simplemente asegúrate de inflar la Vista en el método getView de esta manera.
if (convertView == null)
convertView = LayoutInflater.from(context).inflate(R.layout.yourItemListLayout,
parent, false);
Editar: este trabajo para algunos móviles no todos. Uso la respuesta del Sr. Frank arriba.
Este tipo tenía el mismo problema y más además. Lo resolvió usando ScrollView y LinearLayout en lugar de ListView.