Reputation: 141
I am trying to filter my listview which is populated from a database. Here is my code of activity
listView = (ListView) findViewById(R.id.list1);
listView.setTextFilterEnabled(true);
myAdapter = new MyAdapter(SearchActivity.this, R.layout.list_items_layout);
listView.setAdapter(myAdapter);
list = new ArrayList<>();
mDBHelper = new DatabaseHelper(SearchActivity.this);
sqLiteDatabase = mDBHelper.getReadableDatabase();
cursor = mDBHelper.getAll(sqLiteDatabase);
if(cursor.moveToFirst()){
do{
String id, name, email, contact, fav, cat, audio, count;
id = cursor.getString(0);
name = cursor.getString(1);
email = cursor.getString(2);
contact = cursor.getString(3);
fav = cursor.getString(4);
cat = cursor.getString(5);
audio = cursor.getString(6);
count = cursor.getString(7);
Person person = new Person(id,name,email,contact,fav,cat, audio, count);
myAdapter.add(person);
list.add(person);
} while (cursor.moveToNext());
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Person person = list.get(position);
Intent intent = new Intent(SearchActivity.this, ReceiveDataActivity.class);
intent.putExtra("KEY_ID", person.getId());
intent.putExtra("NAME", person.getName());
intent.putExtra("EMAIL", person.getEmail());
intent.putExtra("CONTACT", person.getContact());
intent.putExtra("FAVORITE", person.getFav());
intent.putExtra("AUDIO", person.getAudio());
intent.putExtra("COUNT", person.getCount());
startActivity(intent);
}
});
SearchButton=(Button)findViewById(R.id.searchButton);
searchName=(EditText)findViewById(R.id.editText);
searchName.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
SearchActivity.this.myAdapter.getFilter().filter(arg0);
myAdapter.notifyDataSetChanged();
}
@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
}
});
the listview is based upon the custom array adapter class
public class MyAdapter extends ArrayAdapter {
List list = new ArrayList();
public MyAdapter(@NonNull Context context, @LayoutRes int resource) {
super(context, resource);
}
@Override
public void add(@Nullable Object object) {
super.add(object);
list.add(object);
}
@Override
public int getCount() {
return list.size();
}
@Nullable
@Override
public Object getItem(int position) {
return list.get(position);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_items_layout,null);
Typeface customFont = Typeface.createFromAsset(this.getContext().getAssets(), "faruma.ttf");
TextView _id = (TextView) convertView.findViewById(R.id.id_here);
TextView _name = (TextView) convertView.findViewById(R.id.name_here);
_name.setTypeface(customFont);
Person person = (Person) list.get(position);
_id.setText(person.getId());
_name.setText(person.getName());
return convertView;
}
When I type a word in edit text the listview is not filtering.
P.S: I am very very new to Android programming (java). I may not understand the explanation but I will be really appreciated with any help.
Upvotes: 0
Views: 42
Reputation: 111
Using the default filter for an adapter is a bit cumbersome, as you need to create an inner class, and override a couple of methods. It's much easier and more readable to implement the following method in the adapter:
public void filter(String charText) {
list.clear(); // clear list
charText = charText.toLowerCase();
if (charText.length() == 0) {
list.addAll(people); // restore original list if no filter is applied
} else {
for (Object item : people) {
Person person = (Person) item;
if (person.getName().toLowerCase().contains(charText)) {
list.add(person); // add item to filtered list if contains string
}
}
}
notifyDataSetChanged();
}
You should also create a second arrayList in the adapter to store a copy of the original items, and a method to initialize it:
private List people = new ArrayList();
public void initPeople() {
people.addAll(list); // copies original list to people list
}
And after your list is populated from the database, you should initialize the people array by calling myAdapter.initPeople(); in SearchActivity.
Finally, in SearchActivity, replace SearchActivity.this.myAdapter.getFilter().filter(arg0); with
SearchActivity.this.myAdapter.filter(arg0.toString());
Upvotes: 1