Ich denke, das ist eine Frage für Experten.
Ich erhalte Anrufe zu getView()
mit positon außerhalb der Grenzen der Datenliste des ListView.
Dies passiert, wenn ich den Adapterfilter verwende. Die Methode des Filters publishResults()
füllt die Daten mit einer gefilterten Liste, die kleiner ist als die ursprüngliche Liste.
Der Fehler scheint aufzutreten, wenn die neue gefilterte Liste kürzer ist als die vorherige gefilterte Liste. Ich habe den Code von getView()
geändert, um ein Dummy-convertView zurückzugeben, wenn es außerhalb der Grenzen liegt, nur um zu sehen, wie viele solcher Aufrufe erfolgen.
Hier sind der relevante Code und die Log
-Nachrichten, die ich geloggt habe:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Keine Logs hier, um die Leistung des ListView zu gewährleisten
Log.d(TAG, "+ getView( position=" + position + ")");
ViewHolder holder;
if( position >= mData.size() ) {
// Dieser Code ermöglicht es, zu sehen, wie viele ungültige Aufrufe ich erhalte
Log.w(TAG, "Position außerhalb der Grenzen!");
convertView = mInflater.inflate(mLayout, parent, false);
return convertView;
}
. . . // Normaler getView-Code
return convertView;
}
Im Filter (Code wie er aus der Quellcode von ArrayAdapter
kopiert wurde)
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Log.pe(TAG, "+ publishResults(constraint:" + constraint + ", results.count:" + results.count + ")");
//noinspection unchecked
mData = (ArrayList) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
Log.px(TAG, "- publishResults()");
}
Die Protokolldatei zeigt, dass nach einem Filter mit 7 Ergebnissen ein Filter mit 3 Ergebnissen kommt, aber getView
weiterhin Aufrufe für 7 Elemente erhält (Ich habe die außerhalb der Grenzen liegenden Aufrufe mit ***
markiert):
02-26 05:31:55.986: D/ViewerActivity(22857): + onQueryTextChange(newText:log)
02-26 05:31:55.986: D/ViewerActivity(22857): - onQueryTextChange()
02-26 05:31:56.029: D/LogScreenAdapter(22857): + performFiltering(prefix:log)
02-26 05:31:56.113: D/dalvikvm(22857): GC_CONCURRENT freed 378K, 5% free 13577K/14215K, paused 0ms+1ms
02-26 05:31:56.153: D/LogScreenAdapter(22857): - performFiltering()
02-26 05:31:56.153: D/LogScreenAdapter(22857): + publishResults(constraint:log, results.count:7)
02-26 05:31:56.167: D/LogScreenAdapter(22857): - publishResults()
02-26 05:31:56.167: D/LogScreenAdapter(22857): + getView( position=0)
02-26 05:31:56.167: D/LogScreenAdapter(22857): + getView( position=0)
02-26 05:31:56.167: D/LogScreenAdapter(22857): + getView( position=0)
02-26 05:31:56.167: D/LogScreenAdapter(22857): + getView( position=1)
. . .
Was Sie hier sehen, ist, dass die Methode publishResults()
die Daten von einer Liste mit 7 Elementen zu einer kürzeren Liste mit 3 Elementen geändert hat, siehe den obigen Code, aber der Adapter
erhält weiterhin getView()
-Aufrufe für die 7-Elemente-Liste, obwohl sie nicht mehr vorhanden ist.
Beachten Sie, dass notifyDataSetChanged()
mit der neuen Datenzuweisung aufgerufen wurde, sodass der ListView
über die neue Liste informiert sein sollte.