OK I have a multiple choice ListView that works fine. I check the boxes for the contacts (held in a String[]) and can return the values fine. Because some people have a bunch of contacts I wanted to create a search bar kind of like the stock one for the Android phone book. I created an EditText and aligned it above my list. I found the filtering code here on StackOverflow and it works wonderfully.
My Problem:
When you filter someones name out, and you select the name, when you either backspace from the EditText or continue typing, the correct position of the name you selected is not saved. For example, if I start typing "Adam" and get to "Ada" and select it, if I backspace to type in "Carol", whatever position "Ada" was at is selected. It gathers the place that "Adam" was at from the click (Let's say 2) and when the list is restored checks that position (2) even though Adam is not there anymore. I need a way to gather the name.. then when the list is restored or searched again, the NAME Adam is checked and not the POSITION Adam was previously at. I have absolutely no ideas other than creating tons of Arrays and could really use some help. Below is some of the code I'm using:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contacts_list);
myListView = (ListView)findViewById(android.R.id.list);
search_EditText = (EditText) findViewById(R.id.search_EditText);
search_EditText.addTextChangedListener(filterTextWatcher);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, ContactsList);
setListAdapter(adapter);
myListView.setItemsCanFocus(false);
getListView().setChoiceMode(2);
myListView.setTextFilterEnabled(true);
myListView.setFastScrollEnabled(true);
myListView.invalidate();
}
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s);
}
};
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 theArrayList
, and if it is unchecked, it is popped from the list. WhenafterTextChanged
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 theEditText
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:
You don't want to use Indexes when using the filters because index 1 might be something in one
ListView
, and it might be anotherListView
item when you change the filter.