Spinner VS AutoCompleteTextView

 

     We’ve all been in a situation where we needed to show a list of some sort, a list which should be triggered by a user interaction (click, tap, etc..)

A list is simple enough, probably even a spinner if we don’t want to spend that much screen real-estate on showing a list which the user clicks once and probably doesn’t need to see it after that.

A spinner can be a real bug once there are too much entries for the user to choose from, how much is too much? that’s a good question – probably it differs from user to user, and probably this will have some performance issues with areal large number of entries, you cannot scroll forever to find what you’re looking for.

A simple solutions for the problems mentioned above is an AutoCompleteTextView.

it’s a control which is basically a combination of a TextView, EditText, and a Spinner all wrapped up in a single easy to use and configurable control.

let’s see how it’s done:

 

first, in the layout file, create an AutoCompleteTextView, you can set it with a lot of attributes which makes it really easy to customize it :

<AutoCompleteTextView
    android:id="@+id/layout_search_rides_spinner_from_city"
    android:layout_width="300dp"
    android:layout_height="wrap_content"
    android:textColor="@color/text_color"
    android:background="@color/titlebar_bg"
    android:layout_centerHorizontal="true"
    android:textSize="25sp"              
    android:completionThreshold="1"
    android:dropDownHeight="200dp"
    android:gravity="center"       
    android:inputType="textAutoComplete"
    android:hint="@string/layout_search_step_1_hint_from"
    android:dropDownWidth="wrap_content"
    android:completionHint="@string/layout_search__hint"
    android:layout_below="@id/layout_search_tv_header" />

special attributes:

  • completionThresgold=”1” , which means that after the user types a single letter,the dropdown lists is shown, I think that the default is 3
  • dropDownHeight=”200dp” , I specified it because I didn’t want it to have a quick snap before the keyboard is shown, which is not to fun to watch, even if it’s for a really short period of time
  • completionHint = @string/layout_search_hint, on the bottom of the dropdown list, a small message will be shown to instruct the user what to do.

in the java side:

the only special thing I did is to show the dropdown list even when the user taps the AutoCompleteTextView , because it’s sometimes intuitive to tap a field to see what happens. this is done by calling the showDropDown() method of AutoCompleteTextView

autoCompleteTextViewFromCity.setOnClickListener(new OnClickListener() {
           
            public void onClick(View v) {
                autoCompleteTextViewFromCity.showDropDown();               
            }
        });

Here’s a quick snap of how it looks like once tapping on the autoCompleteTextView

autocompletetextview

Comments

Unknown said…
Nice post !

Is it possible to have it behave a little more like a "Filterable" Spinner.
This way, the user is forced to select a proposed value and cannot type wathever he want in the field.

I know that it is possible to make validation afterward, but I think it is better to not allow a wrong input.

I tried to implement a serchable Spinner but could'nt get the keyboard to show and get the input caracters.

Thank you,
Guillaume
Israel Tabadi said…
Hi Guillaume,
I suggest putting an EditText and listen to the TextChanged callback, and this way filter the spinner, it might introduce a cool behaviour, i've never seen this kind of control :)

thanks for the comment
Unknown said…
Hi Israel,

Thank you for your input.

I ended up working with a flag and validation indicating that the value must be explicitly clicked from the list.
autoComplete.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view,
int position, long id) {
flag=true;
}
});
autoComplete.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
flag=false;
}

@Override
public void afterTextChanged(Editable s) {
// Nothing
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// Nothing
}

});

Hope this can help someone else.

Guillaume

Popular posts from this blog

How to update UI from a different thread

Utilizing Http response cache