15 Stimmen

Android ListView Array Index übersteigt nach Filtergrenzen

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.

23voto

Abhinav Singh Maurya Punkte 3303

Was geben Sie im public int getCount() Methode des benutzerdefinierten Listenansichtsadapters zurück?

Sie sollten wie mData != null? mData.size() : 0 zurückgeben,

Position außerhalb des Bereichs tritt auf, weil Sie möglicherweise die Größe der Liste zurückgeben, die größer ist als die Daten, die in der Liste angezeigt werden sollen

getCount() Methode des benutzerdefinierten Listenadapters gibt die Größe der Listenansicht an, daher sollte es die Größe der Daten sein, die Sie in der Liste übergeben

21voto

SSemashko Punkte 1499

Scheint, als würde die Überschreibung der Methode "getCount()" Ihr Problem lösen:

@Override
public int getCount() {
    return mData.size();
}

0voto

Groot Punkte 13172

Ich habe das gemacht und es hat meine Probleme gelöst

@Override
public int getCount() {

    if (isFiltered == true) {
        return myFilteredArray.size();
    }

    return myUnfilteredArray.size();
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X