2010-01-24 9 views
91

Sto usando AutoCompleteTextView, quando l'utente fa clic su di esso, voglio mostrare suggerimenti anche se non ha testo - ma setThreshold(0) funziona esattamente come setThreshold(1) - quindi l'utente deve inserire almeno 1 carattere per mostrare i suggerimenti.Android: AutoCompleteTextView mostra suggerimenti quando nessun testo è immesso

+0

Sto facendo qualcosa di simile QUI !!! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42

risposta

117

Questo è documented behavior: "Quando la soglia è inferiore o uguale a 0, viene applicata una soglia di 1".

È possibile visualizzare manualmente la discesa tramite showDropDown(), così forse si può organizzare per mostrare quando si vuole. In alternativa, sottoclasse AutoCompleteTextView e sostituisci enoughToFilter(), restituendo true tutto il tempo.

+4

Lo showDropDown() sembra funzionare bene con l'impostazione di onClickListener, ma la sottoclasse non funziona finché l'utente non immette una lettera e non viene restituita. non solo con onClick ... – amj

+2

Questo funziona perfettamente in combinazione con OnFocusChangeListener che chiama showDropDown() quando la vista ottiene il focus. – Grishka

+0

showDropDown() funziona perfettamente !! –

92

Ecco la mia classe: io la chiamo InstantAutoComplete. È qualcosa tra AutoCompleteTextView e 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); 
     } 
    } 

} 

utilizzarlo nella vostra xml come questo:

<your.namespace.InstantAutoComplete ... /> 
+10

È grandioso! Vorrei anche sottolineare che nel file XML del tuo layout devi cambiare '' per ''. Ho perso un po 'di tempo a comprenderlo :) –

+3

Grande classe: il solo suggerimento sarebbe nel metodo onFocusChanged, cambia "if (focalizzato)" a "if (focused && getAdapter()! = Null)". –

+0

@JulesColle Grazie, modificato –

3

Per rendere CustomAutoCompleteTextView. 1. Override SetThreshold, enoughToFilter, metodo 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; 
    } 
} 
14

codice di Destil funziona solo grande quando v'è un solo InstantAutoComplete oggetto. Non ha funzionato con due se - non ho idea del perché. Ma quando ho messo showDropDown() (proprio come CommonsWare consigliato) in onFocusChanged() come questo:

@Override 
protected void onFocusChanged(boolean focused, int direction, 
     Rect previouslyFocusedRect) { 
    super.onFocusChanged(focused, direction, previouslyFocusedRect); 
    if (focused) { 
     performFiltering(getText(), 0); 
     showDropDown(); 
    } 
} 

ha risolto il problema.

Sono solo le due risposte correttamente combinate, ma spero che possa salvare qualcuno un po 'di tempo.

+1

La tua aggiunta ha aiutato, ma ho ricevuto un errore se c'era del testo in InstantAutoComplete e l'orientamento dello schermo è cambiato. L'ho risolto con un controllo sulla visibilità della finestra, ho postato il nuovo codice qui: https://gist.github.com/furycomptuers/4961368 – FuryComputers

4

È possibile utilizzare onFocusChangeListener;

TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() { 

     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (hasFocus) { 
       TCKimlikNo.showDropDown(); 

      } 

     } 
    }); 
36

modo più semplice:

Basta usare setOnTouchListener e showDropDown()

AutoCompleteTextView text; 
..... 
..... 
text.setOnTouchListener(new View.OnTouchListener(){ 
    @Override 
    public boolean onTouch(View v, MotionEvent event){ 
     text.showDropDown(); 
     return false; 
    } 
}); 
+0

Per rendere ancora più utile l'utilizzo di questo (! Text.isPopupShowing()) { text .showDropDown(); } –

+6

non molto comune, ma questo non funzionerà nel caso in cui l'utente non tocchi per andare a questo EditText. Ad esempio quando si utilizza un telecomando con pulsanti (Android TV, ad esempio). –

+0

Dovresti usare setOnFocusChanged. Qualcuno può avere la tastiera e premere il tasto TAB o usare il mouse e l'ascoltatore touch non sarà chiamato. – barwnikk

5

risposta di Destil sopra quasi funziona, ma ha un bug sottile. Quando l'utente concentra l'attenzione sul campo funziona, tuttavia se lascia e poi torna al campo non mostrerà il menu a discesa perché il valore di mPopupCanBeUpdated sarà ancora falso da quando è stato nascosto. La correzione è quello di cambiare il metodo di 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(""); 
     } 
    } 
} 
+0

ma questo significa anche che il testo sarà resettato (anche se di solito è abbastanza ok) ... –

5

L'adattatore non esegue il filtraggio inizialmente.
Quando il filtro non viene eseguito, l'elenco a discesa è vuoto.
quindi potrebbe essere necessario avviare inizialmente il filtro.

Per fare ciò, è possibile richiamare filter() dopo aver terminato l'aggiunta delle voci:

adapter.add("a1"); 
adapter.add("a2"); 
adapter.add("a3"); 
adapter.getFilter().filter(null); 
0

provare

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; 
      } 
     }): 
2

Basta chiamare questo metodo su Tocca o fai clic caso di autoCompleteTextView o dove tu vuoi.

autoCompleteTextView.showDropDown() 
0

questo ha funzionato per me, pseudo codice:

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); 
    } 
} 

0

semplicemente incollare questo al vostro metodo onCreate in 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(); 

     } 
    }); 

E questo al vostro file XML ...

<AutoCompleteTextView 
      android:layout_width="200dp" 
      android:layout_height="30dp" 
      android:hint="@string/select_location" 
      android:id="@+id/acT1" 
      android:textAlignment="center"/> 

E creare un array in string.xml sotto Valori ...

<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> 

E tu sei a posto.

0

Sette anni dopo, il problema rimane lo stesso. Ecco una classe con una funzione che costringe quello stupido pop-up a mostrarsi in qualsiasi condizione. Tutto quello che devi fare è impostare un adattatore per AutoCompleteTextView, aggiungere alcuni dati al suo interno e chiamare la funzione showDropdownNow() in qualsiasi momento.

Crediti per @David Vávra. È basato sul suo codice.

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) 
     } 
    } 
} 
Problemi correlati