我有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 [],其大小是原始[]的两倍,前半部分包含带重音的单词,第二个包含deaccented版本。所以现在,如果他打字Közé,他将被提供Középmező,如果他输入Koze,他将被提供Kozepmezo。它的工作原理是因为服务器可以处理这两个版本,但它看起来很愚蠢,我想解决它。
根据我的理解,我应该制作一个完整的自定义适配器。这是最好的方法,还是SDK中包含任何解决方案?如果我应该制作自定义适配器,有人能指出我正确的方向,如何做到这一点? :)
编辑:添加了我自己的答案,应该为每个人工作,为其他答案欢呼,这导致我朝着好方向前进!答案 0 :(得分:1)
我确实会选择自定义适配器,您可以在其中提供自己的过滤功能,以匹配重音和重音符号。
可以找到here的示例实现。基本上你需要在performFiltering
中实现实际过滤 - 我假设你已经有办法去除查询,因为你目前正在使用deaccented版本填充你的String[]
。您将需要将带有和不带重音符号的查询与数组中的条目进行比较(您将要使用和不使用重音符号)。最后,您应该至少进行以下四项测试:
accented(query) -> accented(entry)
accented(query) -> deaccented(entry)
deaccented(query) -> accented(entry)
deaccented(query) -> deaccented(entry)
通过即时解除单词,您只需要为String[]
提供带重音的单词,而过滤逻辑(在您的适配器中)将处理与(de)重音单词的匹配。 / p>
如上所述
编辑,在我正在进行的一个项目中的示例实施下面。
一些指示:
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;
}
}
}
答案 1 :(得分:1)
只需按ctrl + c,ctrl + v BaseAdapter的源代码,然后按ctrl + c,ctrl + v ArrayAdapter的源代码。现在看一下私有内部类ArrayFilter,尤其是performFiltering方法。修改(不要覆盖!)它,根据你的需要,在我的情况下,我添加了很多.replace(“x”,“y”)东西,用于去除部分。
无论我尝试了什么,要么产生不可预测的力量关闭(很多,完全随机的),或者我无法做到,因为太多的方法/变量是私有的,而不是受保护的。我必须说,谷歌应该重新审视这些代码...
注意:你真的不需要ctrl + c ctrl + v BaseAdapter代码,因为它是一个公共抽象类,但是,它不是那么多的代码,这样一切都在那里,显然你可以看到。
欢呼声
答案 2 :(得分:0)
看看这个帖子remove-accents-from-string和android Normalizer类
[编辑] 或者您可以尝试使用两个数组merge-adapter