EditText en Listview pierde el foco cuando se presiona en Android 4.x


Sé que hay muchas preguntas similares aquí pero no pude conseguir ninguna de las soluciones proporcionadas trabajando en una aplicación de ejemplo simple.

El problema ocurre cuando el softkeyboard se muestra por primera vez. Tan pronto como se muestra, solo presionando el EditText nuevamente lo hace editable.

Intentó lo siguiente:

 android:windowSoftInputMode="adjustPan|adjustResize"

Esto no está resolviendo ningún problema. Parece que esta línea es obligatoria para tener la actividad redimensionada después del softkeyboard está apareciendo. Desafortunadamente, también está causando que cualquier EditTexts pierda el enfoque. Esto es probablemente para el ListView en sí ganando enfoque después del proceso de redimensionamiento. Así que probé la siguiente solución:

 listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

Esto siempre hace que el primer EditText visible que el ListView contiene para ganar enfoque, lo cual es indeseable. El segundo EditText en la segunda fila debería en su lugar ganar enfoque cuando se presiona, lo que no está sucediendo. Además, si finalmente lograba concentrarme otro EditText que no sea el primero que se muestra (por ejemplo, presionando 'Next' en el softkeyboard), el primero visible recibirá el foco después de que el teclado sea descartado y el ListView sea redimensionado a su tamaño completo de nuevo.

Probé varias otras cosas como interceptar onFocusChange() eventos para la vista de lista, mientras sabía qué EditText estaba presionado por su TouchListener. Solicitar el enfoque para ese cierto EditText de nuevo no condujo a ningún éxito tampoco.

Usando un ScrollView en lugar de un ListView como suggested by other users is not an option either for the concerned project.

Author: Hamad, 2013-12-05

9 answers

Un truco clásico para situaciones como esta es usar un controlador y postDelayed(). En su adaptador:

private int lastFocussedPosition = -1;
private Handler handler = new Handler();

public View getView(final int position, View convertView, ViewGroup parent) {

    // ...

    edittext.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                handler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        if (lastFocussedPosition == -1 || lastFocussedPosition == position) {
                            lastFocussedPosition = position;
                            edittext.requestFocus();
                        }
                    }
                }, 200);

            } else {
                lastFocussedPosition = -1;
            }
        }
    });

    return convertView;
}

Esto funciona en mi dispositivo, pero mantén este código fuera de producción. Tampoco me sorprendería si el error de enfoque se manifiesta de manera diferente en diferentes versiones de Android o roms.

También hay muchos otros problemas con la incrustación de un EditText dentro de un ListView que tienen soluciones que se sienten como un hack. Ver todos los otros la gente luchando.

Es también es muy fácil que algo como esto suceda:

así.

Después de haber ido por caminos similares muchas veces yo mismo, en su mayoría he renunciado a tratar de anular cualquiera de los comportamientos de teclado por defecto o peculiaridades. Recomendaría intentar encontrar una solución alternativa en su aplicación si es posible.

¿Ha considerado que las filas ListView sean solo un TextView con estilo y luego mostrar un Dialog con un EditText cuando se hace clic en una fila, actualizando TextView según sea necesario?

 41
Author: Kyle Ivey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:42

Estaba teniendo problemas con el enfoque de "robar" de la barra de acción cuando presioné un EditText ubicado dentro de una fila de ListView. Las soluciones anteriores no funcionaron, pero la siguiente solución funcionó para mí:

Http://www.mysamplecode.com/2013/02/android-edittext-listview-loses-focus.html

Básicamente agregué esto a mi ListView:

android:descendantFocusability="beforeDescendants"

Y añadí esto a mi actividad:

android:windowSoftInputMode="adjustPan"
 39
Author: gonzobrains,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-16 21:41:41

Modifica tu xml de manifiesto para añadir windowSoftInputMode en tu actividad:

<activity
    android:name=".YourActivity"
    android:windowSoftInputMode="adjustPan">
</activity>
 18
Author: nlmm01,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-16 08:56:07

Sé que es un hilo muy antiguo pero esta respuesta podría ser útil para alguien, así que aquí está:

Cambie a RecyclerView y no tendrá que preocuparse por estos molestos problemas de ListView. En lugar de crear una nueva vista, recicla y reutiliza las vistas antiguas.

 8
Author: ShahrozKhan91,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-27 19:19:34

Use la vista recycler, esto resuelve varios problemas de list y gridview. Incluso puedes trabajar con vistas escalonadas de cuadrícula. Yo podría fácilmente empezar a trabajar con esto http://android-er.blogspot.com.co/2015/07/staggeredgridlayoutmanager-google-app.html

 1
Author: user1176776,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-10 01:03:21

Cuando la lista es lo suficientemente larga como para cubrir el teclado de software, EditText en Listview pierde el foco cuando se presiona en Android 4.x.

Una solución es envolver el Listview en un diseño lineal con una altura de la mitad de la pantalla.

Cuando el Listview no cubre el softkeyboard, todo está bien.

 1
Author: Kai Wang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-18 17:32:14

En mi caso he añadido valor local currentlyFocusedRow en mi Adaptador. En el método getView() he añadido estos códigos a cada EditText:

   if (currentlyFocusedRow == position) {
        editText.requestFocus();
   }

        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    if (currentlyFocusedRow == -1) {
                        currentlyFocusedRow = position;
                    }
                } else {
                    currentlyFocusedRow = -1;
                }
            }
        });
 0
Author: Malder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-18 17:00:38

Estaba teniendo el mismo problema. Se buscaron todas estas soluciones con inputMode, focusability et al. La mejor solución es migrar a la vista recycler.

 0
Author: Aman Agarwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-01 06:36:36

Estaba teniendo el mismo problema con recyclerView y probando todas las soluciones sugeridas.

Finalmente, el problema en mi caso fue que el recyclerView tenía wrap_content como valor para la altura en mi XML por accidente; lo cambió a match_parent y comenzó a funcionar como se esperaba, sin focusable valor establecido y utilizando android:windowSoftInputMode="adjustResize"

 0
Author: Omer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-03 23:15:36