问题
In my Android application I have a multi choice item dialog (similar to that shown in the image) that has a large number of items. So I plan to add a search box and as user types, the items are filtered accordingly. What is the best way to do this? Thanks
回答1:
I did it like this, works fine for me.
private static final class ListItemWithIndex {
public final int index;
public final String value;
public ListItemWithIndex(final int index, final String value) {
super();
this.index = index;
this.value = value;
}
@Override
public String toString() {
return value;
}
}
public static void showMultiChoiceDialogWithSearchFilterUI(final Activity _activity, final Object[] _optionsList,
final int _titleResId, final OnClickListener _itemSelectionListener) {
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(_activity);
final List<ListItemWithIndex> allItems = new ArrayList<ListItemWithIndex>();
final List<ListItemWithIndex> filteredItems = new ArrayList<ListItemWithIndex>();
for (int i = 0; i < _optionsList.length; i++) {
final Object obj = _optionsList[i];
final ListItemWithIndex listItemWithIndex = new ListItemWithIndex(i, obj.toString());
allItems.add(listItemWithIndex);
filteredItems.add(listItemWithIndex);
}
dialogBuilder.setTitle(_titleResId);
final ArrayAdapter<ListItemWithIndex> objectsAdapter = new ArrayAdapter<ListItemWithIndex>(_activity,
android.R.layout.simple_list_item_1, filteredItems) {
@Override
public Filter getFilter() {
return new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(final CharSequence constraint, final FilterResults results) {
filteredItems.clear();
filteredItems.addAll((List<ListItemWithIndex>) results.values);
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(final CharSequence constraint) {
final FilterResults results = new FilterResults();
final String filterString = constraint.toString();
final ArrayList<ListItemWithIndex> list = new ArrayList<ListItemWithIndex>();
for (final ListItemWithIndex obj : allItems) {
final String objStr = obj.toString();
if ("".equals(filterString)
|| objStr.toLowerCase(Locale.getDefault()).contains(
filterString.toLowerCase(Locale.getDefault()))) {
list.add(obj);
}
}
results.values = list;
results.count = list.size();
return results;
}
};
}
};
final EditText searchEditText = new EditText(_activity);
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(final CharSequence arg0, final int arg1, final int arg2, final int arg3) {
}
@Override
public void beforeTextChanged(final CharSequence arg0, final int arg1, final int arg2, final int arg3) {
}
@Override
public void afterTextChanged(final Editable arg0) {
objectsAdapter.getFilter().filter(searchEditText.getText());
}
});
final ListView listView = new ListView(_activity);
listView.setAdapter(objectsAdapter);
final LinearLayout linearLayout = new LinearLayout(_activity);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(searchEditText, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 0);
layoutParams.weight = 1;
linearLayout.addView(listView, layoutParams);
dialogBuilder.setView(linearLayout);
final AlertDialog dialog = dialogBuilder.create();
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
dialog.dismiss();
_itemSelectionListener.onClick(null, filteredItems.get(position).index);
}
});
dialog.show();
}
Just use the "showMultiChoiceDialogWithSearchFilterUI" function. You might want to inflate the edittext and listview from an XML though, because on this solution the views creation is hardcoded.
来源:https://stackoverflow.com/questions/15868940/android-multichoice-item-dialog-with-search-functionality