2017-11-27 1 views
0

Sagen wir, wir kodieren die Facebook-Homepage. Es gibt verschiedene Arten von Zeilen wie Foto-Posts, Werbung, den guten Morgen-Header, Informationen, dass dein Freund einen neuen Freund hat und solche Sachen. Wir würden dafür eine Recyclerview mit mehreren View-Typen verwenden.Wie werden Daten für eine Recyclerview mit mehreren Ansichtstypen behandelt?

Aber wie gehen wir mit den Daten um? Jeder Viewholder benötigt ein anderes POJO-Modell. Wenn es nur einen Ansichtstyp gibt, übergebe ich eine Arraylist mit dem erforderlichen Typ an den Adapter. Aber was in diesem Fall zu tun?

+0

Sie sollten eine Reihe von Generika passieren und auf der Instanz von jeder je Objekt sollten Sie geben das entsprechende Layout/Logik – Ricardo

+0

In diesem Fall wir erstellt beim Aufruf des Adapters verschiedene Modellklassen für die unterschiedliche Layoutstruktur und übergibt den Modellklassennamen und prüft dies mit "instanceOf", um das aktuelle Modell in diesem Layout zu identifizieren. –

+0

Wie eine Arraylist Objekte an Adapter übergeben und sie später werfen? – user6650650

Antwort

0

1- Erstellen einer Klasse, die BaseViewHolderRecyclerView.ViewHolder

2- Neues enum genannt ViewType verlängern:

public enum ViewType { 
    POST, IMAGE, VIDEO 
} 

3- erstellen ViewModel Klasse, die die Daten wie folgt halten wird:

public class ViewModel { 

    ViewType viewType; 
    Object value; 

    pubic ViewType getViewType() { 
     return viewType; 
    } 

    public Object getValue() { 
     return value; 
    } 

    public void setViewType(ViewType viewType) { 
     this.viewType = viewType; 
    } 

    public void setValue(Object value) { 
     this.value = value; 
    } 
} 

4- Ihr RecyclerView-Adapter enthält einen BaseViewHolder:

public class MyAdapter extends RecyclerView.Adapter<BaseViewHolder> { 

    public BaseViewHolder onCreateViewHolder(...) { 

     ViewModel viewModel = new ViewModel(); 

     switch(cardType) { 

      case 1: 

       viewModel.setViewType(ViewType.POST); 
      break; 

      case 2: 

       viewModel.setViewType(ViewType.POST); 

      break; 
     } 

     return BaseViewHolder.createView(viewModel); 
    } 
} 

5- Die BaseViewHolder Klasse:

public class BaseViewHolder extends RecyclerView.ViewHolder { 

    public BaseViewHolder(View itemView) { 

     super(itemView); 

    } 

    public static BaseViewHolder createViewHolder(ViewModel model) { 

     View itemView; 
     switch(model.getViewType()) { 

      case POST: 
      itemView = LayoutInflater.from(getContext()).inflate(R.layout.post_layout); 
      return new PostLayoutViewHolder(itemView, model); 

      case IMAGE: 
      itemView = LayoutInflater.from(getContext()).inflate(R.layout.image_layout); 
      return new ImageLayoutViewHolder(itemView, model); 

     } 

    } 
} 

6- Für jeden Ansichtstyp, erhalten Sie eine ViewHolder Klasse erstellen, die BaseViewHolder erstreckt.

+0

in Betracht ziehen mit Generics lieber als einfaches Objekt –

+0

später in diesem Code, in OnBindViewHolder-Methode, würde ich den Typ des Objekts überprüfen und es umwandeln müssen. Bist du sicher, dass das ein guter Weg ist? – user6650650

+0

nur auf ViewHolder müssen Sie es umwandeln. aber in der OnBindViewHolder müssen Sie den Wert des Objekts festlegen, und rufen Sie 'viewHolder.initializeView()' und dann im ViewHolder sollten Sie das Objekt zu werfen –

1

Sie könnten versuchen, die folgenden:

Bei Modellen eine Basis Dekorateur-Klasse erstellen, wie

public abstract BaseDecorator<T> { 
    private final T model; 

    public BaseDecorator(@NonNull T model){ 
     this.model = model; 
    } 

    public T getModel(){ 
     return model; 
    } 

    public abstract int getViewType(); 

} 

diese Weise erhalten Sie einen Dekorateur, dass Sie Domain-Modell hält und lassen Sie UI bezogene Logik hinzufügen (Viewtype zum Beispiel).

für jede Datenunterklassen erstellen benötigt (POST, FREUND ETC REQUEST) und lassen jede Unterklasse definieren getViewType für jedes Kind einen eindeutigen Wert zurückkehrt (Sie diese Ansicht Typen in einem @IntDef oder Utility-Klasse für sauberere Code speichern kann)

Jetzt benötigt Ihr Adapter nur eine Liste von BaseDecorator, um Daten zu behandeln. Dann können Sie unter onCreateViewHolder den empfangenen viewType wechseln und den richtigen ViewHolder erstellen.

Ofcourse Ihre Adapters außer Kraft setzen getViewType Methode, so etwas wie dieses

@Override 
public int getItemViewType(int position) { 
    return decorators.get(position).getViewType(); 
} 
Verwandte Themen