我确实会选择一个自定义适配器,您可以在其中提供自己的过滤器功能来匹配重音符号和非重音符号。
可以在此处找到执行此操作的示例实现。基本上,您将需要在其中实现实际的过滤performFiltering
-我假设您已经有一种方法可以消除查询,因为您当前正在String[]
使用消除的版本填充您的查询。您需要将带和不带重音的查询与数组中的条目(您希望使用带和不带重音的条目)进行比较。最后你应该至少有以下四个测试:
accented(query) -> accented(entry)
accented(query) -> deaccented(entry)
deaccented(query) -> accented(entry)
deaccented(query) -> deaccented(entry)
通过动态去重音,您只需要提供String[]
带有重音的词,而过滤逻辑(在您的适配器中)将负责匹配(去)重音词。
编辑:正如所讨论的,下面是我正在进行的项目之一的示例实现。
一些指示:
CustomArrayAdapter
主要是简化常见任务的包装类;例如与行包装器/视图持有者的交互。基本上它所需要的只是一个构造函数和实现updateRow
(显然会从超类的getView
方法中调用)。
CustomRowWrapper
应该很简单。
ArrayUtil
并ArrayUtil.FilterFuction
注意实际的过滤。简单地说,这些充当了 for 循环的替代品,该循环构建了一个新列表,其中包含符合某些条件的所有项目。
public class CARMedicationSuggestionAdapter extends CustomArrayAdapter<CARMedicationInfo, RowWrapper> {
private List<CARMedicationInfo> mMedications;
private Filter mFilter;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* constructor
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public CARMedicationSuggestionAdapter(Context context, List<CARMedicationInfo> objects) {
super(RowWrapper.class, context, R.layout.medication_suggestion_item_layout, objects);
// keep copy of all items for lookups
mMedications = new ArrayList<CARMedicationInfo>(objects);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* update row
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@Override protected void updateRow(RowWrapper wrapper, CARMedicationInfo item) {
wrapper.getNameTextView().setText(item.toString());
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* get filter
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@Override public Filter getFilter() {
// return if already created
if (mFilter != null) return mFilter;
mFilter = new Filter() {
@Override protected void publishResults(CharSequence constraint, FilterResults results) {
@SuppressWarnings("unchecked") List<CARMedicationInfo> filtered = (List<CARMedicationInfo>) results.values;
if (results == null || results.count == 0) return;
// clear out current suggestions and add all new ones
clear();
addAll(filtered);
}
@Override protected FilterResults performFiltering(final CharSequence constraint) {
// return empty results for 'null' constraint
if (constraint == null) return new FilterResults();
// get all medications that contain the constraint in drug name, trade name or whose string representation start with the constraint
List<CARMedicationInfo> suggestions = ArrayUtil.filter(mMedications, new ArrayUtil.FilterFunction<CARMedicationInfo>() {
@Override public boolean filter(CARMedicationInfo item) {
String query = constraint.toString().toLowerCase().trim();
return item.mMedicationDrugName.toLowerCase().contains(query) ||
item.mMedicationTradeName.toLowerCase().contains(query) ||
item.toString().toLowerCase().startsWith(query);
}
});
// set results and size
FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
}
};
return mFilter;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* row wrapper
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static class RowWrapper extends CustomRowWrapper {
private ImageView mIconImageView;
private TextView mNameTextView;
public RowWrapper(View row) {
super(row);
}
public ImageView getIconImageView() {
if (mIconImageView == null) mIconImageView = (ImageView) mRow.findViewById(R.id.icon_imageview);
return mIconImageView;
}
public TextView getNameTextView() {
if (mNameTextView == null) mNameTextView = (TextView) mRow.findViewById(R.id.name_textview);
return mNameTextView;
}
}
}