私は確かにカスタムアダプターを選びます。このアダプターでは、アクセント付きとアクセントなしの両方の表記に一致する独自のフィルター関数を提供します。
それを実行する実装例は、ここにあります。基本的に、実際のフィルタリングを実装する必要がありperformFiltering
ます。現在、アクセントのないバージョンを使用しているため、クエリのアクセントを解除する方法がすでにあるString[]
と思います。アクセントがある場合とない場合のクエリを、配列内のエントリ(アクセントがある場合とない場合で使用する)と比較する必要があります。最終的には、少なくとも次の4つのテストが必要です。
accented(query) -> accented(entry)
accented(query) -> deaccented(entry)
deaccented(query) -> accented(entry)
deaccented(query) -> deaccented(entry)
オンザフライで単語のアクセントを解除することによりString[]
、アクセントのある単語を提供するだけで済みますが、(アダプター内の)フィルタリングロジックが(アクセントのない)単語との照合を処理します。
編集:説明したように、進行中のプロジェクトの1つでの実装例を以下に示します。
いくつかのポインタ:
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;
}
}
}