J'utilise AutoCompleteTextView
, lorsque l'utilisateur clique dessus, je veux montrer des suggestions même s'il n'y a pas de texte - mais setThreshold(0)
fonctionne exactement de la même manière que setThreshold(1)
- de sorte que l'utilisateur doit entrer au moins 1 caractère pour afficher les suggestions.
C'est comportement documenté :
Lorsque
threshold
est inférieur ou égal à 0, un seuil de 1 est appliqué.
Vous pouvez afficher manuellement le menu déroulant via showDropDown()
, afin que vous puissiez peut-être le montrer quand vous le souhaitez. Ou, la sous-classe AutoCompleteTextView
et remplacer enoughToFilter()
, retournant true
tout le temps.
Voici ma classe InstantAutoComplete. C'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 ... />
Manière la plus simple:
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 parfaitement lorsqu'il n'y a qu'un seul objet InstantAutoComplete
. Cela n'a pas fonctionné avec deux cependant - aucune idée pourquoi. Mais quand je mets showDropDown()
(comme le préconise 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();
}
}
cela a résolu le problème.
Ce ne sont que les deux réponses bien combinées, mais j'espère que cela fera gagner du temps à quelqu'un.
L'adaptateur n'effectue pas de filtrage initialement.
Lorsque le filtrage n'est pas effectué, la liste déroulante est vide.
vous devrez donc peut-être commencer le filtrage.
Pour ce faire, vous pouvez appeler filter()
après avoir ajouté 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 bogue subtil. Lorsque l'utilisateur donne d'abord le focus au champ, cela fonctionne. Toutefois, s'il quitte puis revient dans le champ, le menu déroulant n'apparaîtra pas car la valeur de mPopupCanBeUpdated sera toujours fausse à partir du moment où elle a été masquée. Le correctif consiste à changer la méthode onFocusChanged en:
@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();
}
}
});
Il suffit d'appeler cette méthode au toucher ou de cliquer sur l'événement de autoCompleteTextView ou à l'endroit souhaité.
autoCompleteTextView.showDropDown()
Pour créer CustomAutoCompleteTextView. 1. override setThreshold, assezToFilter, 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;
}
}
l'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;
}
}):
Sept ans plus tard, le problème reste le même. Voici une classe avec une fonction qui force cette pop-up stupide à se montrer dans toutes les conditions. Tout ce que vous avez à faire est de définir un adaptateur pour votre AutoCompleteTextView, d'y ajouter des données et d'appeler la fonction showDropdownNow()
à tout moment.
Crédits à @David Vávra. C'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)
}
}
}
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);
}
}
Collez-le simplement dans votre méthode 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();
}
});
Et ceci dans 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éez un tableau dans string.xml sous Values ...
<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 prêt à partir.