How to add search capability to an existing ListView.
1. In the XML layout, above your ListView add an EditText widget to receive the user's text input (i.e. the filter).
<EditText
android:id="@+id/et_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
2. Modify your main activity so that it implements the TextWatcher interface.
public class MainActivity extends Activity implements TextWatcher
3. Import this packgage: android.text.TextWatcher.
4. In the onCreate method of your main activity, after registering the EditText with your XML layout, call the addTextChangedListener method.
et_filter.addTextChangedListener(this);
5. The TextWatcher interface requires you to implement three methods. The code below shows the onChanged method connected to your adapter data source. You can leave the other methods empty.
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
6. in your XML Manifest, under android:label add this line to prevent the smartphone's keyboard from displaying when it loads.
android:windowSoftInputMode="stateHidden"
How to use the filtered list
When a filtered list is smaller than the original list size, which is usually the case, the onListItemClick listener will give values for the position and id parameters based on the filtered list.
public void onListItemClick(ListView parent, View v, int position, long id) {}
For example, if "Dragonfruit" is the 10th item in your listView and you filter on the letter "d" and there is only one item that starts with "d" the position and id parameters will return position 0 instead of 9.
You might need the original position if you set up a context menu to do something on items in the listView whether filtered or not such as enabling users to edit the item.
One solution is to get the object from the filtered adapter and search for its index in the original data source such as an arrayList:
// Gets the clicked object in the filtered adapter
String a = (String) parent.getAdapter().getItem(position);
// Finds the index, or position, in the original data source
int startPosInData = MyArrayList.indexOf(a);