Android: AutoCompleteTextView Afficher les suggestions quand aucun texte entré
-
22-09-2019 - |
Question
J'utilise AutoCompleteTextView
, lorsque l'utilisateur clique dessus, je veux montrer des suggestions, même si elle n'a pas de texte - mais setThreshold(0)
fonctionne exactement le même que setThreshold(1)
- afin que l'utilisateur doit entrer au moins 1 caractère pour montrer les suggestions .
La solution
Ceci est comportement documenté :
Lorsque
threshold
est inférieure ou égale à 0, un seuil de 1 est appliquée.
Vous pouvez manuellement afficher le menu déroulant via showDropDown()
, alors peut-être que vous pouvez prendre des dispositions pour le montrer quand vous voulez. Ou, sous-classe AutoCompleteTextView
et override enoughToFilter()
, retour true
tout le temps.
Autres conseils
Voici ma classe InstantAutoComplete . Il est quelque chose entre AutoCompleteTextView
et 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);
}
}
}
Utilisez-le dans votre xml comme ceci:
<your.namespace.InstantAutoComplete ... />
Meilleure façon:
Il suffit d'utiliser setOnTouchListener et showDropDown ()
AutoCompleteTextView text;
.....
.....
text.setOnTouchListener(new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event){
text.showDropDown();
return false;
}
});
Le code de Destil fonctionne bien quand il n'y a qu'un seul objet InstantAutoComplete
. Il ne fonctionne pas avec deux si - aucune idée pourquoi. Mais quand je mets showDropDown()
(comme conseillé CommonsWare) dans onFocusChanged()
comme ceci:
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
performFiltering(getText(), 0);
showDropDown();
}
}
il a résolu le problème.
Il est juste les deux réponses bien combinées, mais je l'espère, il peut sauver quelqu'un un certain temps.
L'adaptateur ne fonctionne pas d'abord le filtrage.
Lorsque le filtrage n'est pas effectuée, la liste déroulante est vide.
de sorte que vous pourriez avoir à obtenir le filtrage va d'abord.
Pour ce faire, vous pouvez appeler filter()
après avoir fini d'ajouter les entrées:
adapter.add("a1");
adapter.add("a2");
adapter.add("a3");
adapter.getFilter().filter(null);
La réponse de Destil ci-dessus fonctionne presque, mais a un bug subtil. Lorsque l'utilisateur donne tout d'abord focus sur le terrain, il fonctionne, s'ils partent et reviennent sur le terrain, il ne sera pas affiché la liste déroulante parce que la valeur de mPopupCanBeUpdated sera toujours faux du moment où il était caché. La solution est de changer la méthode onFocusChanged à:
@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("");
}
}
}
Vous pouvez utiliser onFocusChangeListener;
TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
TCKimlikNo.showDropDown();
}
}
});
Pour CustomAutoCompleteTextView. 1. Commande setThreshold, enoughToFilter, méthode 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;
}
}
Il suffit d'appeler cette méthode sur contact ou cliquez sur l'événement de autoCompleteTextView ou où vous voulez.
autoCompleteTextView.showDropDown()
essayer
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;
}
}):
Cela a fonctionné pour moi, pseudo-code:
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);
}
}
Il suffit de coller ceci à votre onCreate méthode 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();
}
});
Et ceci à votre fichier Xml ...
<AutoCompleteTextView
android:layout_width="200dp"
android:layout_height="30dp"
android:hint="@string/select_location"
android:id="@+id/acT1"
android:textAlignment="center"/>
Et créer un tableau dans string.xml sous Valeurs ...
<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>
Et vous êtes bon pour aller.
Sept ans plus tard, les gars, le problème reste le même. Voici une classe avec une fonction qui force que pop-up stupide de se montrer dans toutes les conditions. Tout ce que vous devez faire est de mettre un adaptateur à votre AutoCompleteTextView, ajouter des données dans, et appeler à tout moment de la fonction showDropdownNow()
.
Crédits à Vávra @ David. Il est basé sur son code.
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)
}
}
}