カスタム ArrayAdapter を使用して、AutocompleteTextView にアダプターを設定しています (AddressAdapter は ArrayAdapter を拡張します)。
public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> mData;
ArrayList<String> listTempPrefix = new ArrayList<String>();
ArrayList<String> listTemp = new ArrayList<String>();
String valueText;
String[] words;
String ulcase;
public AutoCompleteAdapter(Context context, int textViewResourceId, ArrayList<String> bS) {
super(context, textViewResourceId);
mData = bS;//new ArrayList<String>();
}
@Override
public int getCount()
{
synchronized (listTempPrefix)
{
return listTempPrefix.size();
}
}
@Override
public String getItem(int index)
{
synchronized (listTempPrefix)
{
try {
//Log.e("Error", listTempPrefix.get(index));
return listTempPrefix.get(index);
} catch(IndexOutOfBoundsException e) {
Log.e("Error", "IndexOutOfBoundsException");
return "";
}
}
}
@Override
public Filter getFilter()
{
Filter myFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults filterResults = new FilterResults();
synchronized (filterResults)
{
listTempPrefix.clear();
listTemp.clear();
//Log.e("1", "1");
try {
if(constraint != null) {
// A class that queries a web API, parses the data and returns an ArrayList<Style>
//StyleFetcher fetcher = new StyleFetcher();
//try {
//mData = fetcher.retrieveResults(constraint.toString());
//}
//catch(Exception e) {}
// Now assign the values and count to the FilterResults object
for(String value: mData) {
valueText = value.toLowerCase();
//System.out.println("constraintH - " + constraint);
constraint.toString().toLowerCase();
ulcase = constraint.toString().toLowerCase();
//System.out.println("ulcase - " + ulcase);
if (valueText.startsWith(ulcase)) {
listTempPrefix.add(value);
} else {
words = valueText.split(" ");
//final int wordCount = words.length;
// Start at index 0, in case valueText starts with space(s)
for (int k = 0; k < words.length; k++) {
if (words[k].startsWith(ulcase)) {
listTemp.add(value);
break;
}
}
}
///listTemp.add(mData.get(i));
//filterResults.count = mData.size();
// System.out.println("mData" + i + mData.get(i));
}
//Log.e("2", "2");
// System.out.println("size " + listTemp.size() + " value" + listTemp);
listTempPrefix.addAll(listTemp);
filterResults.values = listTempPrefix;
filterResults.count = listTempPrefix.size();
//System.out.println("size " + filterResults.count + " value" + filterResults.values);
//System.out.println("constraint" + constraint);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return filterResults;
}
}
@Override
protected void publishResults(CharSequence contraint, FilterResults filterResults)
{
synchronized (filterResults)
{
if(filterResults != null && filterResults.count > 0) {
notifyDataSetChanged();
//Log.e("notifyDataSetChanged", "notifyDataSetChanged");
}
else {
notifyDataSetInvalidated();
//Log.e("notifyDataSetInvalidated", "notifyDataSetInvalidated");
}
}
}
};
return myFilter;
}
}
私が時々得たもの:注意してください、それは本当にめったに起こりません. しかし、私はこのバグを完全に取り除きたいと思っています。部分的なスタック トレースは次のとおりです。
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(-1, class android.widget.AutoCompleteTextView$DropDownListView) with Adapter(class com.example.test.AutoCompleteAdapter)].
問題は、キーボードからの高速入力、メソッド notifyDataSetChanged() が呼び出されないことです。しかし、よくわかりません。