I never ended up finding a better method than the one I am going to list below. I do not use this code much anymore, and if there is a better solution, I hope someone has it posted somewhere.
What I ended up doing was creating an ArrayList
to hold the selected names. If the name is selected, the name is pushed into the ArrayList
, and if it is unchecked, it is popped from the list. When afterTextChanged
is selected, the list is iterated through and the names are checked if they are currently listed in the adapter. When you finish with the selection process and want to continue, I clear the EditText
to clear the filter, therefore populating the complete list in the ListView and setting all of the contacts to selected if they exist in the ArrayList.
Note, I use a custom adapter for a list of contacts that only list names, so this solution may get more confusing if you use other types of data, and I look at this method as a hacked solution:
/** Used for filter **/
private TextWatcher filterTextWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
ListView listview = getListView();
SparseBooleanArray checked = listview.getCheckedItemPositions();
for (int i = 0; i < ContactsList.length; i++) {
if (checked.get(i) == true) {
Object o = getListAdapter().getItem(i);
String name = o.toString();
// if the arraylist does not contain the name, add it
if (selected.contains(name)){
// Do Nothing
} else {
selected.add(name);
}
}
}
} //<-- End of beforeTextChanged
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
} //<-- End of onTextChanged
public void afterTextChanged(Editable s) {
ListView listview = getListView();
// Uncheck everything:
for (int i = 0; i < listview.getCount(); i++){
listview.setItemChecked(i, false);
}
adapter.getFilter().filter(s, new Filter.FilterListener() {
public void onFilterComplete(int count) {
adapter.notifyDataSetChanged();
ListView listview = getListView();
for (int i = 0; i < adapter.getCount(); i ++) {
// if the current (filtered)
// listview you are viewing has the name included in the list,
// check the box
Object o = getListAdapter().getItem(i);
String name = o.toString();
if (selected.contains(name)) {
listview.setItemChecked(i, true);
} else {
listview.setItemChecked(i, false);
}
}
}
});
} //<-- End of afterTextChanged
}; //<-- End of TextWatcher
You don't want to use Indexes when using the filters because index 1 might be something in one ListView
, and it might be another ListView
item when you change the filter.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…