Hussein Yassine
Yo tengo un AutoCompleteTextView
que está lleno de ciudades de una base de datos sqlite que llama a un AsyncTask
al hacer clic en el elemento, recientemente agregué una opción para detectar mi ubicación usando el gps, por lo que el problema es que puedo detectar la ciudad (es decir, Beirut) y configurar el texto para el AutoCompleteTextView
pero la cuestión es que el filtro desplegable se abre y muestra Beirut (lo cual es correcto), pero todavía necesito hacer clic en el elemento de la lista para invocar al oyente, cómo hacerlo mediante programación
Cómo:
- Ingrese la actividad (HECHO)
- Detectar ubicación (HECHO)
- establecer el texto de la vista de texto (HECHO)
- Mostrar lista desplegable de vista de texto (HECHO)
- elegir el artículo que será devuelto, ya que solo devolverá una ciudad (NO HECHO)
JHowzer
Para ser claros, la solución de Tano es suficiente para responder a esta pregunta. Pero, en caso de que otros se encuentren con el mismo caso de uso que yo, aquí hay más antecedentes que pueden ayudarlo…
Me había encontrado con este problema específicamente al intentar hacer un no editable Menú desplegable Material expuesto y establezca su valor inicial mediante programación. La documentación para crear este tipo de “desplegable” se puede encontrar en la sección Menús Desplegables Expuestos aquílo que sugiere un mecanismo que utiliza TextInputLayout
y AutocompleteTextView
(incluso si no desea la funcionalidad de autocompletar).
Solución fallida 1:
A primera vista setListSelection()
y getListSelection()
parecía que podrían hacer el truco. Pero después de muchas pruebas, aprendí que pueden no ser suficientes porque solo funcionan cuando aparece la lista. isShowing()
. Entonces, por ejemplo, si simplemente desea establecer la selección inicial sin tener que mostrar primero la ventana emergente de la lista, esto no funcionará.
Solución fallida 2:
Entonces lo intenté setText()
que mostró el texto adecuado en mi cuadro de texto. ¡Hurra! ¡Pero espera! Cuando hice clic en la vista de texto, solo se mostró un subconjunto de opciones en la lista emergente por alguna razón. ¿Por qué fue eso? Lo más importante a tener en cuenta aquí es que, dado que se trata de un autocompletar vista de texto, por defecto filtros Opciones de salida basadas en el texto en la vista de texto. Es posible que esto no sea evidente, especialmente si solo usa este control para crear un selector desplegable simple no editable.
Solución:
Esto nos lleva a nuestra solución real (sugerida por Tano)… setText()
con filter
como false
desactivará las capacidades de filtrado Y no cambiará el contenido de la ventana emergente de su lista.
autoCompleteTextView.setText(myText, false);
-
También estoy tratando de usar la vista de texto de autocompletar para crear un buen menú desplegable que se comporte como un Spinner (menos los molestos oyentes que disparan pero con el aspecto agradable que proporciona el textinputlayout). Las soluciones aquí funcionan para configurar el elemento seleccionado en función del texto, pero me gustaría tener todas las opciones disponibles cuando toca la función de autocompletar. En este momento todavía tendría que eliminar el texto para que aparezcan todos. ¿Algunas ideas? ¿O hay alguna manera de hacer que un Spinner se vea como el diseño de entrada de texto delineado?
– JPM
26 de julio de 2019 a las 2:02
-
Esta es una respuesta brillante y bien explicada. El único problema que tengo es que la opción de filtro requiere un nivel de API de 17
– dave o grady
3 de marzo de 2020 a las 0:41
-
@JPM, puede mostrar una lista desplegable en cualquier momento, consulte stackoverflow.com/a/26036902/2914140. Actualmente abre la lista completa (primera vez) incluso si se ha ingresado algún texto. Cuando edita un texto, filtra elementos. Tal vez stackoverflow.com/a/60791879/2914140 funciona, no lo verifiqué.
– CoolMind
2 de junio de 2020 a las 12:39
-
Pasé un par de horas en las soluciones fallidas mencionadas aquí, y ahora estoy así de cerca de un cambio de carrera después de desarrollar aplicaciones de Android durante 8 años.
– SafaOrhan
1 oct 2021 a las 15:25
tano
Estaba enfrentando un problema similar y esto resolvió mi problema. importante es llamar setText(<text>, <filter boolean>)
para no filtrar con el texto dado establezca el segundo parámetro con false
. El texto se obtendrá del adaptador desplegable.
Fragmento de solución:
automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(position).toString(), false);
-
¡Gracias! Pienso,
false
es un valor predeterminado. Entonces, podemos usarautoCompleteTextView.setText(someText);
.– CoolMind
2 de junio de 2020 a las 13:01
-
Funciona perfectamente gracias!
– DAVE SUCIO
16 de enero a las 9:59
Una solución donde no necesita cambiar su nivel de API.
automCompleteTextView.setAdapter(adapter);
// set default selection, filtering is active so all items is not visible in drop-down menu
automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(0).toString());
// change filtering for the adapter so all items can be visible in drop-down menu
adapter.getFilter().filter(null);
one-liner para el mismo trabajo pero requiere un nivel de API más alto
automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(0).toString(), false);
Me di cuenta después de profundizar en el código AutoCompleteTextView en el código fuente de Android:
fun AutoCompleteTextView.selectItem(text: String, position: Int = 0) {
this.setText(text)
this.showDropDown()
this.setSelection(position)
this.listSelection = position
this.performCompletion()
}
autoComplete.setListSelection(position);
-
esto no selecciona el elemento para mí si la lista no se muestra
– DAVE SUCIO
16 de enero a las 9:57
he utilizado autoCompleteTextView.setText(myText, false);
solución también, sin embargo, a veces fallaba. Quiero decir que estaba filtrando activamente los resultados, por lo que, cuando el usuario hace clic, solo había 1 elemento en el menú desplegable.
Además, también necesitaba esto para trabajar en objetos personalizados, y esta es mi solución:
binding.hourEditText.configureDropDownMenu(viewModel.hours) { it.hourString() }
.subscribe {
// Do whatever you need when on click.
}
.addTo(disposables)
fun <T> AutoCompleteTextView.configureDropDownMenu(list: List<T>, toString: ((T) -> String)? = null): Observable<T> {
keyListener = null
val textItems = toString?.let(list::map) ?: list.map { it.toString() }
setAdapter(NonFilterArrayAdapter(context!!, android.R.layout.simple_spinner_dropdown_item, textItems))
return itemClickEvents().map {
list[it.position]
}
}
private class NonFilterArrayAdapter<T>(context: Context, @LayoutRes resource: Int, objects: List<T>) : ArrayAdapter<T>(context, resource, objects) {
override fun getFilter() = NonFilter()
private class NonFilter : Filter() {
override fun performFiltering(constraint: CharSequence?) = FilterResults()
override fun publishResults(constraint: CharSequence?, results: FilterResults?) = Unit
}
}
Nota: Esto también contiene un poco de Rx, pero se puede eliminar fácilmente.
-
esto no selecciona el elemento para mí si la lista no se muestra
– DAVE SUCIO
16 de enero a las 9:57
Intente agregar a continuación después de setText () en AutoCompleteTextview: –
autoCompleteTV.setSelection(position);
Actualizado:
Esto funcionará en Spinner
y AutoCompleteTextView
que tiene una función desplegable, pero no funcionará con EditText
.
Aquí puede consultar los documentos para AbsSpinner
en este enlace:
https://developer.android.com/reference/android/widget/AbsSpinner.html#setSelection(int)
-
@HusseinYassine Déjame revisar mi trabajo y regresaré con la solución.
– Nitin Patel
7 de julio de 2017 a las 6:35
-
setSelection es una forma abreviada de dónde colocar el cursor sin seleccionar un elemento en el Adaptador.
– Chris Jenkins
18 de agosto de 2019 a las 22:15
-
@Chris.Jenkins Para su aclaración, consulte este enlace desarrollador.android.com/reference/android/widget/… y aún no lo obtuve después de la inicialización, solo intente con una posición diferente.
– Nitin Patel
19 de agosto de 2019 a las 12:39
-
@NitinPatel Sí, eso es para un
AbstractSpinner
,AutoCompleteTextView
no es eso.setSelection
en unaEditText
establece la posición del cursor, no la selección de elementos en un control giratorio.– Chris Jenkins
20 de agosto de 2019 a las 14:01
-
Esto puede provocar un bloqueo: ‘java.lang.IndexOutOfBoundsException: setSpan (43 … 43) termina más allá de la longitud 34’. Usar
setListSelection
en cambio.– CoolMind
2 de junio de 2020 a las 13:44