我正在将a larger GTK/Python program的部分内容重写为Android。在其中一个编辑文本中,我的用户将输入一个植物分类名称,其中包括 Pachypharynx 或 Erythroxylaceae 等字样。
这些词是“植物词典”的一部分,而说不同语言的人会以不同的方式发音,并且在输入时会产生不同的输入错误。有些人具有准同音异义词,如/ Hieronima / Hyeronima / Hieronyma / group,其中前两个被归类为大戟科,后者被归类为Phyllanthaceae。有些是有效的名称,但有更好的选择(例如:Coccus被认为是Cocos的同义词)
那么编程问题在哪儿?好吧,我想帮助用户!
TextView
,TextView
中,我需要帮助用户输入名称我考虑过并放弃了以下内容:
我想
AutoCompleteTextView
(但如何?)我认为这个问题值得一提(我不知道为什么你们这些人/女士在没有解释的情况下投票)并且我认为我找到和建立的答案会帮助其他人。
答案 0 :(得分:1)
这个答案建立在其他人的基础之上,但最重要的是Carl Anderson's。它基于AutoCompleteTextView选项,我将在解决方案的每个元素上逐一查看。
首先,在创建视图时,让我们抓住ACTV并将其与自定义适配器关联:
public View onCreateView([...]) {
.
.
TaxonomyDatabase db = new TaxonomyDatabase(getContext());
List<Epithet> allEpithets = db.getAllGenera();
EpithetAdapter hints = new EpithetAdapter(getContext(),
android.R.layout.select_dialog_item, allEpithets);
AutoCompleteTextView widget = rootView.findViewById(R.id.etCollectSpecies);
widget.setThreshold(2); // start hinting from second character
widget.setAdapter(hints);
TaxonomyDatabase.getAllGenera
从数据库中获取所有属,包括它们所接受的等价物,以及它们所属的家族。
List<Epithet> getAllGenera() {
ArrayList<Epithet> r = new ArrayList<>();
SQLiteDatabase db = getReadableDatabase();
Cursor cr = db.rawQuery(
"select o.epithet, a.epithet, o.phonetic, a.family_name " +
"from taxon o "+"" +
"left join taxon a on o.accepted_id = a.id " +
"where o.rank = 5 " +
"order by o.epithet",
new String[]{});
.
.
现在,EpithetAdapter构造函数接受此列表,首先将其添加到其内部候选列表中,然后再次在列表中再次复制每个Epithet:第一个实例用于文字匹配,第二个实例用于允许语音匹配。其中的逻辑隐藏在Epithet复制构造函数中,它将isExact
字段设置为false
。
EpithetAdapter(Context context, int textViewResourceId, List<Epithet> epithets) {
super(context, textViewResourceId, epithets);
// copy all the epithets twice
mEpithets = new ArrayList<>(epithets.size() * 2);
// first to be used as exact matches (String×4 constructor)
mEpithets.addAll(epithets);
// then again to be used as phonetic matches (copy constructor)
for(Epithet e : epithets) {
mEpithets.add(new Epithet(e));
}
}
Epithet类有一个toString方法,用于处理Epithet在ACTV下拉列表中的显示方式:
public String toString() {
if (accepted != null) {
return epithet + " → " + accepted;
} else {
return epithet + " (" + family + ")";
}
}
EpithetAdapter中的过滤器执行剩下的任务:当用户点击建议时,会调用ConvertResultToString
:
public String convertResultToString(Object resultValue) {
return ((Epithet)resultValue).epithet;
}
过滤自身,即performFiltering
方法,只是迄今为止所有人所说的逻辑结果:
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null) {
String exact = constraint.toString();
String phonetic = TaxonomyDatabase.phonetic(exact);
exact = exact.substring(0, 1).toUpperCase() + exact.substring(1).toLowerCase();
ArrayList<Epithet> suggestions = new ArrayList<>();
for (Epithet epithet : mEpithets) {
if (epithet.isExact) {
if (epithet.epithet.startsWith(exact)) {
suggestions.add(epithet);
}
} else {
if (epithet.phonetic.startsWith(phonetic) &&
!epithet.epithet.startsWith(exact)) {
suggestions.add(epithet);
}
}
}
results.values = suggestions;
results.count = suggestions.size();
}
return results;
}
android:inputType="textNoSuggestions"
),以免污染用户词典。当用户输入coccus时,软件建议:
当用户输入»galanth«时,文字匹配首先出现:
当用户输入»calanth«时,再次出现字面匹配:
您在下拉列表中看到的是Epithet.toString
。单击提示仅复制Epithet.epithet
。