2017-03-31 1 views
0

Ich habe eine ListView, die von einem ArrayAdapter aufgefüllt wird, und ich muss eine Anzeige nach jedem N-ten legitimen Listenelement einfügen. Der einfachste Weg, von dem ich denken kann, dies zu tun wäre, um das Array zu ändern, die der Adapterdatensatz direkt definiert (oder indirekt über ArrayAdapter :: hinzufügen/Insert) wie folgt:Wie fügt man ein Listenelement in listview ein, ohne den zugrunde liegenden Datensatz zu ändern?

/** 
* Injects ad entries into the station list after every N legit entries 
* 
* @param adapter the arrayadapter that will generate the views representing our legit and ad list items 
*/ 
private void injectAdEntries(MyArrayAdapter adapter){ 
    int legitItemCount = adapter.getCount(); 
    int adStride = 4; 
    if(legitItemCount >= adStride) { 
     //adstride-1 to account for the 0 index 
     for (int legitItemIndex = adStride-1; legitItemIndex < legitItemCount; legitItemIndex += adStride) { 
      //create clone of last legit entry, to use as context 
      // data for the ad, and mark it 'illegitimate' (ad) 
      LegitObject totallyLegit = new LegitObject(adapter.getItem(legitItemIndex)); 
      totallyLegit.setLegit(false); 
      adapter.insert(totallyLegit,legitItemIndex+1); 

     } 
    } 
} 

Nach der Injektion MyArrayAdapter der getView override kann den falschen legit-Wert erkennen und Werbungseinträge anders als legitime Einträge behandeln.

Das Problem ist, dass ich das legitime Datenarray nicht verschmutzen will. Idealerweise würde ich diese Werbebuchungselemente einfügen, ohne den zugrunde liegenden Datensatz zu verändern. Gibt es eine Möglichkeit, einen Adapter dazu zu bringen, Ansichten zu erstellen, die sich nicht in seinem Datensatz widerspiegeln?

bearbeiten

Ich brauche auch alle Elemente in den legitimen Datensatzes in der Listview angezeigt werden; Die Werbebuchungselemente müssen "zusätzlich zu" anstelle von "legitimen Listenelementen" angezeigt werden.

Antwort

1

Ich gehe davon aus, dass Sie eine RecyclerView als Liste verwenden. Also, heterogenes Layouts (dh: TATSÄCHLICHE ITEM LAYOUT + AD LAYOUT) sollten Sie die folgenden Schritte aus:

  1. Aufschalten getItemView wie

    @Override 
    public int getItemViewType(int position) { 
        // insert an Ad every multiple of 5 
        if (position % 5 == 0) { 
         return AD_POSITION; 
        } 
        return NORMAL_POSITION; 
    } 
    
  2. Als nächstes müssen Sie die onCreateViewHolder Methode außer Kraft setzen um die RecyclerView.Adapter zu erzählen, über die RecyclerView.ViewHolder Objekt basierend auf der viewType zurückgegeben wurde.

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 
        RecyclerView.ViewHolder viewHolder; 
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext()); 
    
        switch (viewType) { 
         case AD_POSITION: 
          View v1 = inflater.inflate(R.layout.list_item_ad, viewGroup, false); 
          viewHolder = new AdViewHolder(v1); 
          break; 
         default: 
          // NORMAL_POSITION 
          View v = inflater.inflate(R.layout.list_item, viewGroup, false); 
          viewHolder = new NormalViewHolder(v); 
          break; 
        } 
        return viewHolder; 
    } 
    

Für weitere Informationen können Sie dieses link out überprüfen.

+0

+1 für den Vorschlag, aber meine aktuelle Implementierung basiert auf ListView + ArrayAdapter, und idealerweise würde ich gerne eine Lösung finden, die innerhalb dieses Rahmens (wenn möglich) funktioniert. Außerdem bin ich mir nicht sicher, ob ich mich einer solchen neuen Framework-Klasse (RecyclerView wurde in API-Level 22 hinzugefügt) jetzt verpflichten sollte, da sich die minimale Support-API-API-Stufe bis auf eine Ebene von 9 [https: // developer .android.com/topic/libraries/support-library/index.html # api-versions] - Ich muss auf absehbare Zeit wieder auf 16 zurückgreifen. – CCJ

+0

Müsste dieser Ansatz nicht immer noch den zugrunde liegenden Datensatz modifizieren? Die Adapter- und Layout-Positionen von RecyclerView müssen von dem Datensatz abgeleitet werden, der dem RecyclerView.Adapter zugewiesen wurde (ich denke), so dass Sie zwar heterogene Daten mit dem Vorteil einer Positionsansicht, die durch die Position bestimmt ist, anzeigen können, diese Daten jedoch immer noch benötigen eine einzelne Quelle. Würden im obigen Beispiel nicht die normalen Einträge an Positionen, die ein Vielfaches von 5 sind, zugunsten einer Anzeige fallen gelassen werden? Wie auch immer, mein Ziel ist es, die Daten der normalen Listeneinträge so weit wie möglich von den Anzeigen getrennt zu halten. – CCJ

+0

Für Ihren ** ersten Kommentar **, ich denke, Sie werden nur mehr Leistung (speziell) gewinnen und nichts verlieren, wenn Sie zu RecyclerView wechseln, und wenn Sie zurück zu API 9 unterstützen, unterstützen Sie fast mehr als 99% von Android-Handys. Für Ihren ** zweiten Kommentar ** weiß ich nicht wirklich viel über Ihre Daten (die Sie an den Adapter weitergeben), aber ich bin mir sicher, dass Sie nicht viele Anpassungen vornehmen müssen, damit es funktioniert. –

Verwandte Themen