2015-07-21 1 views
6

Ich entwickle eine Anwendung, die stark auf der Verwendung von RecyclerView basiert.So verwenden Sie den gleichen RecyclerView Adapter für verschiedene Layouts

Ich muss wirklich wissen, wie man den gleichen RecyclerView für verschiedene Artikellayouts verwendet. Ein Beispiel für Layouts sind:

1) Ein Listenelement mit einem Namen und eine Beschreibung

2) Ein Listenelement mit einem Bild und einen Namen

Sie können sehen, dass sie ähnlich, aber mit leichtem Änderungen am Layout

Vielen Dank im Voraus!

+0

Sie müssen mehr Details über Ihre App geben - sonst ist es schwer, eine Empfehlung zu geben – ligi

Antwort

4

Da das recyclingview-Element in XML nicht von der Art der Elemente abhängt, die Sie darin auffüllen, können Sie die gleiche Recycler-Ansichtslayoutdatei für die drei Fragmente verwenden.

Wie bei den Adaptern scheinen Ihre Listen homogen zu sein (d. H. Eine Art von Ansichtselement). Es ist das Beste, dass Sie für jeden Fall 3 verschiedene Adapter verwenden. Sie können den Konstruktor anpassen und benutzerdefinierte Hilfsmethoden für jede Art von Adapter nach Belieben hinzufügen.

Nun, wenn Sie eine heterogene Liste haben, werden Sie diese getItemViewType() in Ihrem Adapter und verwenden in geeigneter Weise in onCreateViewHolder() und onBindViewHolder() außer Kraft setzen müssen

hoffe, das hilft! :)

3

Ich stieß auf ähnliche Situation und hier ist das Modell, dem ich folgte.

Zunächst einmal Fragment Layout-Datei.

Fragment-Layout-Datei wird nicht für alle 3 Fragmente ändern (im Grunde ist es ähnlich zu Listenfragment), so habe ich eine Vorlage für die Liste Fragment erstellt.

list_fragment_template.xml 

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/list" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 

</FrameLayout> 

Jetzt Fragment Code:

In meinem Fall alle drei Fragmente tun fast gleiche Material (Recycler Ansicht erhalten, erhalten Adapter, Recycler Ansicht Dekoration und einige weitere Operationen usw.).

Erstellt ein AbstrctFragment, das Fragment erweitert und onCreate onAttach onDestroy usw. überschrieben. Da nur Typ der Datenrecyclerview konsumiert und Adapter zum Push-Daten für reycelrview für jedes der Fragment ändern würde, erstellen Sie eine abstrakte Funktion zu GetAdapter und Templatize Daten. Jedes der drei Fragmente wird von diesem AbstractFragment abgeleitet.

... onAttach onDetach und was auch immer gemeinsame Memberfunktionen und Membervariablen für jedes Fragment kommt.

Jetzt RecyclerView Layout-Dateien. Da alle im Layout unterschiedlich sind, müssen sie natürlich anders sein.

RecyclerViewAdapters: Auch hier wäre Common-Code zu Member-Deklarationen, CreateViewHolder (hier nur Layout-Namen Änderungen Rest alle Code ist gleich) und jede andere Funktion, die alle diese Adapter teilen würde. (etwas wie das Filtern von Listenelementen).

ähnlich, wie wir für Fragmente haben, können Sie dies in AbstractRecyclerViewAdapter halten und bindViewholder etc als abstrakte Funktionen machen und 3 verschiedene recyclerAdapters haben, die von dieser AbstractRecyclerViewAdapter ableiten würde ..

-1
//To setViewType maybe is a solution for you.Sample below: 
private static final int TYPE_DESC = 0; 
private static final int TYPE_IMAGE = TYPE_DESC + 1; 
private static final int TYPE_THREE_TEXT = TYPE_IMAGE + 1; 
public int getItemViewType(int position) { 
    int type = super.getItemViewType(position); 
    try 
    { 
     type = Integer.parseInt(data.get(position).get("type")); 
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    return type; 
} 

public int getViewTypeCount() { 
    return 3; 
} 
public View getView(int position, View convertView, ViewGroup parent) { 
    int type = TYPE_DESC; 
    try 
    { 
     type = Integer.parseInt(data.get(position).get("type")); 
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    ViewHolder holder = null; 
    if (convertView == null) 
    { 
     System.out.println("getView::convertView is null"); 
     holder = new ViewHolder(); 
     switch (type) 
     { 
      case TYPE_DESC: 
       convertView = View.inflate(getBaseContext(), 
         R.layout.listitem_1, null); 
       break; 
      case TYPE_IMAGE: 
       convertView = View.inflate(getBaseContext(), 
         R.layout.listitem_2, null); 
       break; 
      case TYPE_THREE_TEXT: 
       convertView = View.inflate(getBaseContext(), 
         R.layout.listitem_3, null); 
       break; 
     } 
     convertView.setTag(holder); 
    } 
    else 
    { 
     holder = (ViewHolder) convertView.getTag(); 
    } 
    //TODO 
    return convertView; 
} 
+0

Dies ist keine RecyclerView.Adapter-Unterklasse. OP möchte Hilfe mit RecyclerView speziell :) –

0

es zu spät ist, aber, vielleicht für jemand bedürftig Entwickler nützlich sein Ihr Adapter sollte wie folgt aussehen, fügen Sie können auch Kopf- und Fußzeilen diese Probe mit

public class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> { 

// Declaring Variable to Understand which View is being worked on 
// IF the view under inflation and population is header or Item 
private static final int TYPE_HEADER = 0; 
private static final int TYPE_ITEM = 1; 
private static final int TYPE_FOOTER = 2; 

private Activity mContext; 
private ArrayList<DataModel> _mItems; 
private int mLayout; 
private String mProductHeadingTitle="Heading"; 
private String mProductHeadingSubTitle="SubHeading"; 
private String loadingText="LOADING"; 
private int visibility= View.VISIBLE; 

public interface SampleAdapterInterface { 
    void itemClicked(int position); 
} 

SampleAdapterInterface mCallBack; 

public SampleAdapter(Activity context, ArrayList<DataModel> items, int item_layout) { 
    if (_mItems != null) { 
     _mItems.clear(); 
    } 
    this.mContext = context; 
    this._mItems = items; 
    this.mLayout = item_layout; 
    mCallBack = (SampleAdapterInterface) context; 
} 

@Override 
public int getItemCount() { 
    return _mItems.size()+2; // +2 for header and footer 
} 

@Override 
public int getItemViewType(int position) { 

    if (position==0) 
     return TYPE_HEADER; 
    else if(position==(_mItems.size()+1)) 
     return TYPE_FOOTER; 

    return TYPE_ITEM; 
} 

public void setHeaderData(String title,String subTitle) 
{ 
    this.mProductHeadingTitle=title; 
    this.mProductHeadingSubTitle=subTitle; 

    Log.d("LOG", "ProductHeadingTitle: " + mProductHeadingTitle); 
    Log.d("LOG", "ProductHeadingSubTitle: " + mProductHeadingSubTitle); 

    notifyDataSetChanged(); 
} 

public void setFooterData(String loadingText,int visibility) 
{ 
    this.loadingText=loadingText; 
    this.visibility=visibility; 

    Log.d("LOG", "LoadingText: " + loadingText); 
    Log.d("LOG", "Visibility: " + visibility); 

    notifyDataSetChanged(); 
} 

@Override 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 


    if (viewType == TYPE_HEADER) 
    { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_layout,parent,false); 

     ViewHolder vhHeader = new ViewHolder(view,viewType); 

     return vhHeader; 
    } 
    else if (viewType == TYPE_ITEM) 
    { 
     View view = LayoutInflater.from(parent.getContext()).inflate(mLayout,parent,false); 

     //Creating ViewHolder and passing the object of type view 
     ViewHolder vhItem = new ViewHolder(view,viewType); 

     return vhItem; 
    } 
    else if (viewType == TYPE_FOOTER) 
    { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_lyout,parent,false); 

     ViewHolder vhFooter = new ViewHolder(view,viewType); 

     return vhFooter; 
    } 
    return null; 
} 

@Override 
public void onBindViewHolder(ViewHolder viewHolder, int pos) { 


    if(viewHolder.Holderid ==0) 
    { 
     // header view 
     Log.d("LOG", "in header binder"); 
     viewHolder.mProductCatalogTitle.setText(mProductHeadingTitle); 
     viewHolder.mProductCatalogSubTitle.setText(mProductHeadingSubTitle); 
    } 
    else if(viewHolder.Holderid==1) 
    { 
     final int position=pos-1; // -1 to substract header number 
     // your code 
    } 
    else if(viewHolder.Holderid==2) 
    { 
     // footer 
     Log.d("LOG", "in footer binder"); 
     viewHolder.mProgressBar.setVisibility(visibility); 
     viewHolder.mLoading.setText(loadingText); 
    } 


} 

class ViewHolder extends RecyclerView.ViewHolder { 

    int Holderid; 

    // header 
    TextView mProductCatalogTitle; 
    TextView mProductCatalogSubTitle; 

    //list 
    // item type variable declaration 

    // footer 
    ProgressBar mProgressBar; 
    TextView mLoading; 

    public ViewHolder(View itemView, int viewType) { 
     super(itemView); 
     // Here we set the appropriate view in accordance with the the view type as passed when the holder object is created 
     if(viewType == TYPE_HEADER) 
     { 
      Holderid = 0; 
      mProductCatalogTitle = (TextView) itemView.findViewById(R.id.tv_title); 
      mProductCatalogSubTitle = (TextView) itemView.findViewById(R.id.tv_subtitle); 
     } 
     else if(viewType == TYPE_ITEM) 
     { 
      Holderid = 1; 
      itemView.setClickable(true); 
      itemView.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        mCallBack.itemClicked(getAdapterPosition()-1); 
       } 
      }); 
      // initialize the view holder 
     } 

     else if(viewType == TYPE_FOOTER) 
     { 
      Holderid = 2; 
      mLoading = (TextView) itemView.findViewById(R.id.tv_loading); 
      mProgressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar); 
     } 
    } 
} 

in Ihrer Tätigkeit

und Ihre Aktivität muss SampleAdapterInterface in Aktivität implementieren, um einen Rückruf vom Adapter zu erhalten. Rufen Sie diese Methoden beim Umschalten der Schaltfläche vom Raster zur Liste und umgekehrt