Android: AutoCompleteTextView muestran sugerencias cuando no hay texto introducido
-
22-09-2019 - |
Pregunta
Estoy utilizando AutoCompleteTextView
, cuando el usuario hace clic en él, que quieren mostrar sugerencias, incluso si no tiene ningún texto - pero setThreshold(0)
funciona exactamente igual que setThreshold(1)
- por lo que el usuario tiene que introducir al menos 1 carácter para mostrar las sugerencias .
Solución
Este es comportamiento documentado :
Cuando
threshold
es menor que o igual a 0, un umbral de 1 es aplicada.
Se puede mostrar manualmente el desplegable a través de showDropDown()
, así que tal vez se puede organizar para mostrar que cuando se desea. O, AutoCompleteTextView
subclase y enoughToFilter()
anulación, volviendo true
todo el tiempo.
Otros consejos
Esta es mi clase InstantAutoComplete . Es algo entre AutoCompleteTextView
y Spinner
.
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.AutoCompleteTextView;
public class InstantAutoComplete extends AutoCompleteTextView {
public InstantAutoComplete(Context context) {
super(context);
}
public InstantAutoComplete(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
public InstantAutoComplete(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
@Override
public boolean enoughToFilter() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused && getAdapter() != null) {
performFiltering(getText(), 0);
}
}
}
El uso en el código XML siguiente:
<your.namespace.InstantAutoComplete ... />
La manera más fácil:
Sólo uso setOnTouchListener y showDropDown ()
AutoCompleteTextView text;
.....
.....
text.setOnTouchListener(new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event){
text.showDropDown();
return false;
}
});
Código de Destil funciona muy bien cuando sólo hay un objeto InstantAutoComplete
. No funcionó con dos a pesar - ni idea de por qué. Pero cuando pongo showDropDown()
(al igual que aconsejó CommonsWare) en onFocusChanged()
como esto:
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
performFiltering(getText(), 0);
showDropDown();
}
}
resolvió el problema.
Es sólo las dos respuestas adecuadamente combinados, pero espero que puede salvar a alguien algún tiempo.
El adaptador no realiza el filtrado inicialmente.
Cuando no se realiza el filtrado, la lista desplegable está vacía.
lo que podría tener para obtener el filtrado de ir al principio.
Para hacerlo, puede invocar filter()
después de haber terminado la adición de las entradas:
adapter.add("a1");
adapter.add("a2");
adapter.add("a3");
adapter.getFilter().filter(null);
La respuesta de Destil por encima de casi funciona, pero tiene un error sutil. Cuando el primer usuario sitúa el foco en el campo funciona, sin embargo, si se van y luego vuelven al campo, no se mostrará el menú desplegable porque el valor de mPopupCanBeUpdated seguirá siendo falsa desde el momento en que estaba oculto. La solución es para cambiar el método OnFocusChanged a:
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
if (getText().toString().length() == 0) {
// We want to trigger the drop down, replace the text.
setText("");
}
}
}
Se puede utilizar onFocusChangeListener;
TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
TCKimlikNo.showDropDown();
}
}
});
Para hacer CustomAutoCompleteTextView. 1. override setThreshold, enoughToFilter, método OnFocusChanged
public class CustomAutoCompleteTextView extends AutoCompleteTextView {
private int myThreshold;
public CustomAutoCompleteTextView (Context context) {
super(context);
}
public CustomAutoCompleteTextView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomAutoCompleteTextView (Context context, AttributeSet attrs) {
super(context, attrs);
}
//set threshold 0.
public void setThreshold(int threshold) {
if (threshold < 0) {
threshold = 0;
}
myThreshold = threshold;
}
//if threshold is 0 than return true
public boolean enoughToFilter() {
return true;
}
//invoke on focus
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
//skip space and backspace
super.performFiltering("", 67);
// TODO Auto-generated method stub
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
protected void performFiltering(CharSequence text, int keyCode) {
// TODO Auto-generated method stub
super.performFiltering(text, keyCode);
}
public int getThreshold() {
return myThreshold;
}
}
Sólo tiene que llamar a este método en toque o haga clic en caso de AutoCompleteTextView o donde quiera.
autoCompleteTextView.showDropDown()
probarlo
searchAutoComplete.setThreshold(0);
searchAutoComplete.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {//cut last probel
if (charSequence.length() > 1) {
if (charSequence.charAt(charSequence.length() - 1) == ' ') {
searchAutoComplete.setText(charSequence.subSequence(0, charSequence.length() - 1));
searchAutoComplete.setSelection(charSequence.length() - 1);
}
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
//when clicked in autocomplete text view
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.header_search_etv:
if (searchAutoComplete.getText().toString().length() == 0) {
searchAutoComplete.setText(" ");
}
break;
}
}):
Esto funcionó para mí, pseudo código:
public class CustomAutoCompleteTextView extends AutoCompleteTextView {
public CustomAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean enoughToFilter() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
performFiltering(getText(), 0);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
this.showDropDown();
return super.onTouchEvent(event);
}
}
Sólo tienes que pegar esto a su método onCreate en Java
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
this, android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.Loc_names));
textView1 =(AutoCompleteTextView) findViewById(R.id.acT1);
textView1.setAdapter(arrayAdapter);
textView1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View arg0) {
textView1.setMaxLines(5);
textView1.showDropDown();
}
});
Y esto a su archivo XML ...
<AutoCompleteTextView
android:layout_width="200dp"
android:layout_height="30dp"
android:hint="@string/select_location"
android:id="@+id/acT1"
android:textAlignment="center"/>
Y crear una matriz en string.xml en Valores ...
<string-array name="Loc_names">
<item>Pakistan</item>
<item>Germany</item>
<item>Russia/NCR</item>
<item>China</item>
<item>India</item>
<item>Sweden</item>
<item>Australia</item>
</string-array>
y que son buenos para ir.
Siete años más tarde, chicos, el problema sigue siendo el mismo. Aquí está una clase con una función que las fuerzas que estúpida emergente para manifestarse en cualquier condición. Todo lo que necesita hacer es fijar un adaptador para su AutoCompleteTextView, añadir algunos datos en él, y la función de llamada showDropdownNow()
en cualquier momento.
Los créditos a @ David Vávra. Se basa en su código.
import android.content.Context
import android.util.AttributeSet
import android.widget.AutoCompleteTextView
class InstantAutoCompleteTextView : AutoCompleteTextView {
constructor(context: Context) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun enoughToFilter(): Boolean {
return true
}
fun showDropdownNow() {
if (adapter != null) {
// Remember a current text
val savedText = text
// Set empty text and perform filtering. As the result we restore all items inside of
// a filter's internal item collection.
setText(null, true)
// Set back the saved text and DO NOT perform filtering. As the result of these steps
// we have a text shown in UI, and what is more important we have items not filtered
setText(savedText, false)
// Move cursor to the end of a text
setSelection(text.length)
// Now we can show a dropdown with full list of options not filtered by displayed text
performFiltering(null, 0)
}
}
}