141

I am using AutoCompleteTextView, when the user clicks on it, I want to show suggestions even if it has no text - but setThreshold(0) works exactly the same as setThreshold(1) - so the user has to enter at least 1 character to show the suggestions.

Draken
  • 3,134
  • 13
  • 34
  • 54
fhucho
  • 34,062
  • 40
  • 136
  • 186
  • I am doing something similiar HERE!!! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – Etienne Lawlor Oct 30 '12 at 19:48

15 Answers15

176

This is documented behavior:

When threshold is less than or equals 0, a threshold of 1 is applied.

You can manually show the drop-down via showDropDown(), so perhaps you can arrange to show it when you want. Or, subclass AutoCompleteTextView and override enoughToFilter(), returning true all of time.

Alireza Noorali
  • 3,129
  • 2
  • 33
  • 80
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 8
    The showDropDown() seem to work well on seting onClickListener,but subclass thing is not working untill the user enter a letter and comes dels back.But not just with onClick... – amj Feb 20 '13 at 18:15
  • 10
    This works just perfectly in combination with OnFocusChangeListener that calls showDropDown() when the view gains the focus. – Grishka Feb 06 '14 at 17:55
  • I have to also override the onFocusChanged, as stated on the answer below by @David Vávra – Gabriel Feb 01 '17 at 21:16
  • 5
    @commonsWare `showDropDown()` isn't working in `afterTextChanged` when `.getText().toString().length()==0`. WHYYY – Prabs Apr 26 '17 at 06:02
  • 1
    Only overriding enoughToFilter helps me. Thank you! – Fedir Tsapana Sep 21 '18 at 12:05
  • works like a charm. use setOnFocusChangeListener then call showDropDown() on the AutocompleteTextView. – M Umer Nov 02 '19 at 13:52
137

Here is my class InstantAutoComplete. It's something between AutoCompleteTextView and 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);
        }
    }

}

Use it in your xml like this:

<your.namespace.InstantAutoComplete ... />
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
David Vávra
  • 18,446
  • 7
  • 48
  • 56
55

Easiest way:

Just use setOnTouchListener and showDropDown()

AutoCompleteTextView text;
.....
.....
text.setOnTouchListener(new View.OnTouchListener(){
   @Override
   public boolean onTouch(View v, MotionEvent event){
      text.showDropDown();
      return false;
   }
});
user1913469
  • 559
  • 4
  • 3
  • 1
    To make this even better use if(!text.isPopupShowing()){ text.showDropDown(); } – Boldijar Paul Dec 15 '14 at 12:57
  • 7
    not much common, but this won't work in case the user doesn't touch in order to go to this EditText. For example when using a remote control with buttons (Android TV, for example). – android developer Dec 31 '14 at 00:27
  • 2
    You should use setOnFocusChanged. Somebody can have keyboard and press TAB button or using mouse and touch listener will not be called. – barwnikk Aug 29 '15 at 04:00
  • onTouchListener will get called different times for a single tap - Ex: the event can be MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP. So its better to check for a specific event and write the code – Govind Dec 30 '16 at 11:42
  • Wasted 2 whole day and you solved my problem man, thnx alot. @user1913469 – Himani Aug 18 '21 at 07:29
18

Destil's code works just great when there is only one InstantAutoComplete object. It didn't work with two though - no idea why. But when I put showDropDown() (just like CommonsWare advised) into onFocusChanged() like this:

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

it solved the problem.

It is just the two answers properly combined, but I hope it may save somebody some time.

alex
  • 10,900
  • 15
  • 70
  • 100
  • 2
    Your addition helped, but I got an error if there was text in the InstantAutoComplete and the screen orientation changed. I fixed it with a check on the window visibility, I posted the new code here: https://gist.github.com/furycomptuers/4961368 – FuryComputers Feb 15 '13 at 16:25
11

The adapter does not perform filtering initially.
When the filtering is not performed, the dropdown list is empty.
so you might have to get the filtering going initially.

To do so, you can invoke filter() after you finish adding the entries:

adapter.add("a1");
adapter.add("a2");
adapter.add("a3");
adapter.getFilter().filter(null);
david m lee
  • 2,547
  • 26
  • 14
7

You can use onFocusChangeListener;

TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {

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

            }

        }
    });
Göksel Güren
  • 1,479
  • 13
  • 21
7

Destil's answer above almost works, but has one subtle bug. When the user first gives focus to the field it works, however if they leave and then return to the field it will not show the drop down because the value of mPopupCanBeUpdated will still be false from when it was hidden. The fix is to change the onFocusChanged method to:

@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("");
        }
    }
}
Colin Stewart
  • 572
  • 3
  • 2
5

Just call this method on touch or click event of autoCompleteTextView or where you want.

autoCompleteTextView.showDropDown()
Dalvinder Singh
  • 1,073
  • 1
  • 12
  • 19
3

To make CustomAutoCompleteTextView. 1. override setThreshold,enoughToFilter,onFocusChanged method

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; 
    } 
}
Community
  • 1
  • 1
1

try it

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

Seven years later, guys, the problem stays the same. Here's a class with a function which forces that stupid pop-up to show itself in any conditions. All you need to do is to set an adapter to your AutoCompleteTextView, add some data into it, and call showDropdownNow() function anytime.

Credits to @David Vávra. It's based on his 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)
        }
    }
}
mykolaj
  • 974
  • 8
  • 17
1

on FocusChangeListener, check

if (hasFocus) {
            tvAutoComplete.setText(" ")

in your filter, just trim this value:

filter { it.contains(constraint.trim(), true) }

and it will show all suggestion when you focus on this view.

beokh
  • 191
  • 2
  • 3
0

This worked for me, 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);
    }
}

Nasif Md. Tanjim
  • 3,862
  • 4
  • 28
  • 38
0

Just paste this to your onCreate Method 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();

        }
    });

And this to your Xml file...

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

And create an Array in string.xml under 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>

And you are good to go.

Lalit Fauzdar
  • 5,953
  • 2
  • 26
  • 50
-1

For me, It is :

 autoCompleteText.setThreshold(0);

do the trick.

gmyboy
  • 81
  • 1
  • 7