2016-06-19 16 views
-1

Ich versuche, 2 verschiedene Objektansichten anzuzeigen, je nachdem, was ich in meiner Array-Liste habe. Ohne die Bedingung (wenn) gibt es kein Problem, aber wenn ich die Bedingung stelle und ich mich mit 2 viewHolders befassen muss, bekomme ich eine Fehlermeldung, dass viewHolder nicht von viewHolder umgewandelt werden kann.viewHolder konnte nicht von viewHolder

Hier ist mein Code:

@Override 
public View getView(int position, View view, ViewGroup parent) { 

    bind(getItem(position), view); 

    return view; 
} 


private void bind(final Eddystone eddystone, final View view) { 

     List<Content> contents = ... ; 

     if(contents.get(i).content_type_id==2){ 

      ViewHolder holder = (ViewHolder) view.getTag(); 
      // some code here 
     } 
     else { 

      ViewHolderVideo holder = (ViewHolderVideo) view.getTag(); 
      // some code here 
     } 

} 

der Fehler auf dem zweiten Halter ist (in anderem Zustand).

Bitte denken Sie daran, wenn ich die Bedingung (die sonst) entfernen, funktioniert es perfekt, und die Klasse, in der dieser Code geschrieben wird, ist ein Adapter.

Bitte jede Hilfe ist willkommen.

Danke :)

Antwort

1

Das Problem ist, Listview die falsche Zeile ist das Recycling. Zur Zeit denkt ListView, dass alle Zeilen gleich sind, weil Sie nicht gesagt haben, dass es mehr als eine Art von Zeile gibt.

Ihr Adapter muss getItemViewType() und getViewTypeCount() implementieren. Diese beiden Methoden geben ListView die Anzahl der Zeilenarten an und welche Zeilentypen welchen Positionen entsprechen, so dass die richtigen Zeilenansichten wiederverwendet werden können.

gegeben, was du gepostet hast, wird wahrscheinlich die Umsetzung wie folgt aussehen:

private static final int VIEW_TYPE_DEFAULT = 0; 
private static final int VIEW_TYPE_VIDEO = 1; 

@Override 
public int getViewTypeCount() { 
    return 2; 
} 

@Override 
public int getItemViewType(int position) { 
    // return a value between zero (inclusive) and the total item type count (exclusive) 
    if (contents.get(position).content_type_id == 2) { 
     return VIEW_TYPE_VIDEO; 
    } 
    return VIEW_TYPE_DEFAULT: 
} 

Sie können dann wieder die Ansicht Typ überprüfen innerhalb von getView():

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    int type = getItemViewType(position); 
    if (type == VIEW_TYPE_VIDEO) { 
     return buildVideoRow(position, convertView, parent); 
    } else if (type == VIEW_TYPE_DEFAULT) { 
     return buildDefaultRow(position, convertView, parent); 
    } 
    return null; // or throw an IllegalStateException, because something is wrong if you get here. 
} 

private View buildVideoRow(int position, View convertView, ViewGroup parent) { 
    VideoViewHolder holder; 
    if (convertView != null) { 
     holder = (VideoViewHolder) convertView.getTag(); 
    } else { 
     convertView = ... // inflate row here 
     // set the tag, etc. 
    } 
    ... // bind views here 
    return convertView; 
} 

private View buildDefaultRow(int position, View convertView, ViewGroup parent) { 
    // similar implementation as buildVideoRow() 
} 
+0

Dank für Ihre anwser, Ich habe verstanden, aber das Problem in meinem Code, die Inhaltsliste wird in einer CallBack() initiiert, so dass ich eine Null-Referenz Ausnahme in getItemViewType mit contents.get (i). Die Inhaltsliste wird in der buildVideoRow innerhalb einer onSuccess-Methode des Callbacks gestartet:/Haben Sie eine Idee, wie Sie dies lösen können? –

+0

@AymaneBo Laden Sie zuerst Ihre Daten, bevor Sie versuchen, sie in einer Liste anzuzeigen, oder laden Sie den Teil, der den Zeilentyp bestimmen kann, und laden Sie den Rest später. Der Adater sollte nicht für das Laden der Liste verantwortlich sein; tun Sie das in Ihrer Aktivität oder in Ihrem Fragment und übergeben Sie dann die geladene Liste an den Adapter, indem Sie 'notifyDataSetChanged()' aufrufen, wenn Sie die ListView aktualisieren müssen. – Karakuri