I want to implement a SearchView
in Android for partial word search.
I have made the following search mechanism, how do I get partial word search functionality?
Eg. If I search for "stackover..", stackoverflow appears but if I search for "tackover.." stackoverflow doesn't appear, I need it to search for partial matches in words.
package jagranerp.myapplication;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
public class MainActivity extends Activity {
// List view
private ListView lv;
// Listview Adapter
ArrayAdapter<String> adapter;
// Search EditText
EditText inputSearch;
// ArrayList for Listview
ArrayList<HashMap<String, String>> productList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Listview Data
String products[] = {"Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "HTC Sensation XE",
"iPhone 4S", "Samsung Galaxy Note 800",
"Samsung Galaxy S3", "MacBook Air", "Mac Mini", "MacBook Pro"};
lv = (ListView) findViewById(R.id.list_view);
inputSearch = (EditText) findViewById(R.id.inputSearch);
// Adding items to listview
adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.product_name, products);
lv.setAdapter(adapter);
/**
* Enabling Search Filter
* */
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
}
}
I was interested in doing something similar to this requirement myself so I played around with some stuff. As a result this code isn't just a short snippet / quick fix.
I created my own
CustomArrayAdapter
which extendsBaseAdapter
and is mostly based on the source code for ArrayAdapter. I havent implemented methods that add, remove or modify items in the adapter's list but those methods can easily be copied / adapted from the source (NOTE those methods usesynchronize
to make the adapter thread-safe - be sure to follow that model).The key thing is to create your own
Filter
which inArrayAdapter
is an inner private class so it's not just a simple case of extendingArrayAdapter
directly.The answer from chntgomez points in the right direction - the
Filter
forArrayAdapter
simply usesstartsWith(...)
to match the constraint. It first tries it on the start of the complete string and then attempts to split the string (using space char as a delimiter) to check to see if multi-word stringsstartWith(...)
the constraint (prefix).By changing the use of
startsWith(...)
tocontains(...)
you can achieve a 'match' on an individual char or sequence of characters. The code to split any multi-word strings can also be removed as it's not necessary.The following
CustomArrayAdapter
and itsFilter
works withActivity
posted in the original question (obviously changingArrayAdapter
to beCustomArrayAdapter
instead).