我有3个AutoCompleteTextViews,我想在它们上注册2个String[]适配器。目前,我正在做这件事:
atw_from.setAdapter(new ArrayAdapter(ctx, android.r.layout.simple_dropdown_item_1line, stages_adapter));假设我的用户想要输入"Középmező",他开始输入"Közé“,系统会提供他选择Középmező,直到现在,它非常简单。但是,如果用户懒得输入重音(其中很多都是懒惰的),那么他将只输入Kozepmezo,那么他将不会得到任何报价,因为我的String[]中没有Kozepmezo。我想要的是,如果他输入"Koze",应该为他提供Középmező,所以即使他不使用重音,他也总是会得到带有重音的实际单词。
目前,我有一个相当愚蠢的解决方案,我有一个String[],它的大小是原来的[]的两倍,前半部分包含带重音的单词,第二部分包含去重音的版本。所以现在,如果他输入Közé,他将被提供给Középmező,如果他输入Koze,他将被提供Kozepmezo。它之所以有效,是因为服务器可以处理这两个版本,但它看起来很愚蠢,我想解决它。
据我所知,我应该做一个完全自定义的适配器。这是最好的方法吗,或者SDK中包含了什么解决方案?如果我要做定制适配器,有没有人能给我指个方向,告诉我该怎么做?:)
编辑:添加了我自己的答案,应该为每个人工作,为另一个答案干杯,这让我朝着好的方向前进!
发布于 2012-04-10 17:26:34
好了,在经历了这么多的痛苦之后,我在最后做了一件事。这根本不是一个好的实践,我可能做错了,但至少它现在工作得很好。
简单的ctrl+c,ctrl+v BaseAdapter的源代码,ctrl+c,ctrl+v ArrayAdapter的源代码。现在看看私有内部类ArrayFilter,特别是performFiltering方法。修改(而不是覆盖!)在我的例子中,我添加了很多.replace("x","y")作为去重音部分。
不管我怎么尝试,要么产生不可预测的强制关闭(很多,完全随机的),要么我就是做不到,因为太多的方法/变量是私有的,而不是受保护的。我必须说,谷歌应该重新审视这些代码。
注意:您实际上不需要ctrl+c ctrl+v BaseAdapter代码,因为它是一个公共抽象类,但是,它并不是那么多的代码,这样一切都在那里,对您来说是清晰可见的。
干杯
发布于 2012-04-05 03:38:27
我确实会选择一个自定义适配器,在这个适配器中,您可以提供自己的过滤器函数来匹配重音和非重音符号。
这样做的一个示例实现可以在here中找到。基本上,你需要在performFiltering中实现实际的过滤-我假设你已经有了去重音查询的方法,因为你现在正在用去重音版本填充你的String[]。您需要将带和不带重音的查询与数组中的条目进行比较(您需要使用带和不带重音的数组)。最后,您至少应该有以下四个测试:
accented(query) -> accented(entry)
accented(query) -> deaccented(entry)
deaccented(query) -> accented(entry)
deaccented(query) -> deaccented(entry)通过对单词进行动态去重读,您只需向String[]提供重读单词,而过滤逻辑(在适配器中)将负责与(去)重读单词进行匹配。
编辑:已经讨论过的,下面是我正在进行的一个项目中的示例实现。
以下是一些建议:
CustomArrayAdapter主要是一个包装类,它简化了常见的任务;例如,与行包装器/视图持有器的交互。基本上,它所需要的只是一个构造函数和updateRow的实现(显然会从超类的getView中调用),而ArrayUtil.FilterFuction负责实际的过滤。简单地说,它们作为for循环的替代品,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;
}
}
}发布于 2012-04-01 22:03:59
看看这个线程remove-accents-from-string和android Normalizer类
编辑,或者您可以尝试对这两个阵列使用merge-adapter
https://stackoverflow.com/questions/9658308
复制相似问题