我会选择自定义适配器,其中您可以提供自己的过滤函数来匹配带重音和去重音符号的标记。
一个实现这一点的示例可以在这里找到。基本上,您需要在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;
}
}
}