Autocomplete TextView in Android
AutocompleteTextView is an editable text view that shows completion suggestions automatically while the user is typing. The list of suggestions is displayed in a drop down menu from which the user can choose an item to replace the content of the edit box with.
The drop down can be dismissed at any time by pressing the back key or, if no item is selected in the drop down, by pressing the enter/dpad center key.
The list of suggestions is obtained from a data adapter and appears only after a given number of characters defined by the threshold.
The following code snippet shows how to create a auto complete text view which suggests various fruit names while the user is typing:
MainActivity.java
package com.example.demoproject;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatAutoCompleteTextView;
import android.widget.ArrayAdapter;public class MainActivity extends AppCompatActivity {private String[] fruits = {“Apple”, “Appy”, “Banana”, “Cherry”, “Date”, “Grape”, “Kiwi”, “Mango”, “Pear”};
private AppCompatAutoCompleteTextView autoTextView;@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
autoTextView = (AppCompatAutoCompleteTextView) findViewById(R.id.autoTextView);ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this, android.R.layout.select_dialog_item, fruits);
autoTextView.setThreshold(1); //will start working from first character
autoTextView.setAdapter(adapter);
}
}
activity_main.xml
<?xml version=”1.0" encoding=”utf-8"?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android"
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:layout_margin=”16dp”
android:orientation=”vertical”><android.support.v7.widget.AppCompatAutoCompleteTextView
android:id=”@+id/autoTextView”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:hint=”Enter fruit name”
android:textColor=”#000000"
android:textColorHint=”#000000" /></LinearLayout>
In the above code, we’ve stored the list of fruits in an ArrayAdapter with a layout android.R.layout.select_dialog_item
imported from the Android SDK and a threshold count of 1 depicts that to show the autocomplete drop-down list we need to type in at least one character.
Here’s the output:
Above example is for static auto complete textview that shows only single text in dropdown menu. We can change its layout and can add more controls in dropdown menu as an option. Let’s start for customized autocomplete textview.
Fruit.java (Model class/POJO)
public class Fruit {private int image;
private String name;
private String desc;public int getImage() {
return image;
}public void setImage(int image) {
this.image = image;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public String getDesc() {
return desc;
}public void setDesc(String desc) {
this.desc = desc;
}
}
Layout for custom row for auto complete textview custom_row.xml
<?xml version=”1.0" encoding=”utf-8"?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android"
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:orientation=”horizontal”
android:padding=”8dp”><ImageView
android:id=”@+id/imageView”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content” /><TextView
android:id=”@+id/textView”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:padding=”4dp”
android:textColor=”#000000"
android:textSize=”18sp” /></LinearLayout>
Custom Adapter for Autocomplete TextView FruitAdapter.java:
package com.example.demoproject;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;public class FruitAdapter extends ArrayAdapter<Fruit> {private Context context;
private int resourceId;
private List<Fruit> items, tempItems, suggestions;public FruitAdapter(@NonNull Context context, int resourceId, ArrayList<Fruit> items) {
super(context, resourceId, items);
this.items = items;
this.context = context;
this.resourceId = resourceId;
tempItems = new ArrayList<>(items);
suggestions = new ArrayList<>();
}@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = convertView;
try {
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
view = inflater.inflate(resourceId, parent, false);
}
Fruit fruit = getItem(position);
TextView name = (TextView) view.findViewById(R.id.textView);
ImageView imageView = view.findViewById(R.id.imageView);
imageView.setImageResource(fruit.getImage());
name.setText(fruit.getName());
} catch (Exception e) {
e.printStackTrace();
}
return view;
}@Nullable
@Override
public Fruit getItem(int position) {
return items.get(position);
}@Override
public int getCount() {
return items.size();
}@Override
public long getItemId(int position) {
return position;
}@NonNull
@Override
public Filter getFilter() {
return fruitFilter;
}private Filter fruitFilter = new Filter() {
@Override
public CharSequence convertResultToString(Object resultValue) {
Fruit fruit = (Fruit) resultValue;
return fruit.getName();
}@Override
protected FilterResults performFiltering(CharSequence charSequence) {
if (charSequence != null) {
suggestions.clear();
for (Fruit fruit: tempItems) {
if (fruit.getName().toLowerCase().startsWith(charSequence.toString().toLowerCase())) {
suggestions.add(fruit);
}
}FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
} else {
return new FilterResults();
}
}@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
ArrayList<Fruit> tempValues = (ArrayList<Fruit>) filterResults.values;
if (filterResults != null && filterResults.count > 0) {
clear();
for (Fruit fruitObj : tempValues) {
add(fruitObj);
}
notifyDataSetChanged();
} else {
clear();
notifyDataSetChanged();
}
}
};
}
Now add images for fruits, create static list for fruits for dropdown and set adapter to autocomplete textview.
MainActivity.java
package com.example.demoproject;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatAutoCompleteTextView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;public class MainActivity extends AppCompatActivity {private ArrayList<Fruit> fruitArrayList;
private AppCompatAutoCompleteTextView autoTextViewCustom;
private TextView fruitDesc;
private FruitAdapter fruitAdapter;@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);fruitDesc = (TextView) findViewById(R.id.fruitDesc);
autoTextViewCustom = (AppCompatAutoCompleteTextView) findViewById(R.id.autoTextViewCustom);// fill fruit list
fruitArrayList = new ArrayList<>();fruitArrayList.add(new Fruit(R.drawable.apple, “Apple”, “The apple tree is a deciduous tree in the rose family best known for its sweet, pomaceous fruit, the apple.”));fruitArrayList.add(new Fruit(R.drawable.banana, “Banana”, “The banana is an edible fruit — botanically a berry — produced by several kinds of large herbaceous flowering plants in the genus Musa.”));fruitArrayList.add(new Fruit(R.drawable.cherries, “Cherry”, “A cherry is the fruit of many plants of the genus Prunus, and is a fleshy drupe (stone fruit).”));fruitArrayList.add(new Fruit(R.drawable.grapes, “Grape”, “A grape is a fruit, botanically a berry, of the deciduous woody vines of the flowering plant genus Vitis.”));fruitArrayList.add(new Fruit(R.drawable.kiwi, “Kiwi”, “Kiwifruit or Chinese gooseberry is the edible berries of several species of woody vines in the genus Actinidia.”));fruitArrayList.add(new Fruit(R.drawable.mango, “Mango”, “Mangoes are juicy stone fruit from numerous species of tropical trees belonging to the flowering plant genus Mangifera, cultivated mostly for their edible fruit.”));fruitArrayList.add(new Fruit(R.drawable.pear, “Pear”, “The pear is any of several tree and shrub species of genus Pyrus, in the family Rosaceae.”));fruitAdapter = new FruitAdapter(this, R.layout.custom_row, fruitArrayList);autoTextViewCustom.setThreshold(1);
autoTextViewCustom.setAdapter(fruitAdapter);// handle click event and set desc on textview
autoTextViewCustom.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Fruit fruit = (Fruit) adapterView.getItemAtPosition(i);
fruitDesc.setText(fruit.getDesc());
}
});
}
}
Here’s the output:
Here we have 3 list in Adapter. items
, tempItems
and suggestions
.
- items
for original list passed from activity code.
- tempItems
for closing original one and do compare with editable character from user
- suggestions
for actual filter dropdown values