2015-07-21 23 views
6

Zajmuję się tworzeniem aplikacji, która w dużym stopniu opiera się na wykorzystaniu RecyclerView.Korzystanie z tego samego adaptera RecyclerView dla różnych układów

Naprawdę potrzebuję wiedzieć, jak używać tego samego RecyclerView dla różnych układów przedmiotów. Przykładem układów są:

1) Element listy z nazwą i opisem

2) Element listy z obrazem i nazwą

Widać, że są one podobne, ale z niewielkimi zmiany w układzie.

Z góry dziękuję!

+0

Musisz podać więcej szczegółów na temat swojej aplikacji - w przeciwnym razie trudno jest podać rekomendację – ligi

Odpowiedz

4

Ponieważ element recyclerview w formacie xml nie zależy od rodzaju przedmiotów, które można w nim pompować, można użyć tego samego pliku układu widoku recyklingu dla trzech fragmentów.

Jeśli chodzi o adaptery, twoje listy wydają się być jednorodne (tzn. Pojedynczy rodzaj elementu widoku). Najlepiej używać 3 różnych adapterów dla każdego przypadku. Można dostosować konstruktor, dodać niestandardowe metody pomocnicze dla każdego rodzaju adaptera zgodnie z wygodą użytkownika.

Teraz, jeśli masz listę heterogenicznych, trzeba będzie zastąpić getItemViewType() w karty i użyć tego odpowiednio w onCreateViewHolder() i onBindViewHolder()

nadzieję, że to pomaga! :)

3

Natknąłem się na podobną sytuację i oto model, który podążałem.

Po pierwsze, Plik fragmentu układu.

Plik układu fragmentu nie zmieni się dla wszystkich 3 fragmentów (w zasadzie jest podobny do fragmentu listy), więc utworzyłem plik szablonu dla fragmentu listy.

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> 

kod Teraz fragment:

W moim przypadku wszystkie 3 fragmenty zrobić prawie same rzeczy (dostać widok recykler, dostać kartę, recykler widok dekoracji i jeszcze kilka operacji etc).

Utworzono AbstrctFragment, który rozszerza fragment i nadpisuje onCreate onAttach onDestroy itp. Ponieważ tylko typ recyklingu danych zużywa i adaptery do przekazywania danych do recycelrview zmieni się dla każdego z fragmentów, utwórz abstrakcyjną funkcję, aby pobrać Adaptor i dokonać templatalizacji danych. Każdy z trzech fragmentów będzie pochodził z tego AbstractFragment.

public abstract class AbstractFragment<E> extends Fragment { 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     // Inflate the layout for this fragment 
     View view = inflater.inflate(R.layout.template_list_fragment, container, false); 


      mRecyclerView = (RecyclerView) view.findViewById(R.id.list); 

      // get adapter to show item list 
      // and fetch data. 
      mRecyclerAdapter = getAdapter(); 
      mRecyclerView.setAdapter(mRecyclerAdapter); 

      // show it as vertical list 
      mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
      // add seperator between list items. 
      mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); 

return view; 
    } 

... onAttach onDetach i cokolwiek wspólnego memberfunctions i zmiennych członkowskich, które przychodzi dla każdego fragmentu.

Teraz Pliki układu RecyclerView. Ponieważ wszystkie z nich różnią się układem, oczywiście muszą być inne.

RecyclerViewAdapters: Znów w tym miejscu wspólnym kodem byłyby deklaracje członków, CreateViewHolder (tutaj tylko zmiany nazwy layoutu spoczywają cały kod jest taki sam) i każda inna funkcja, którą wszystkie te adaptery mogłyby udostępniać. (coś w rodzaju filtrowania elementów listy).

podobny do tego, jak to zrobiliśmy dla fragmentów, można mieć to na AbstractRecyclerViewAdapter i uczynić bindViewholder etc jako abstrakcyjnych funkcji i posiada 3 różne recyclerAdapters, które wynikają z tego AbstractRecyclerViewAdapter ..

-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

To nie jest podklasa RecyclerView.Adapter. OP chce pomocy z RecyclerView specjalnie :) –

0

jej zbyt późno, ale, może być pomocny dla kogoś potrzebującego dewelopera Twój adapter powinien wyglądać tak, też można dodać nagłówek i stopkę przy użyciu tej próbki

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); 
     } 
    } 
} 

w swojej działalności

// Adding to adapter as gridview when grid button clicked 
private void setProductGridAdapter() { 
    mListViewTab.setVisibility(View.VISIBLE); 
    mGridViewTab.setVisibility(View.INVISIBLE); 

    mSampleAdapter = new SampleAdapter(YourActicity.this, 
      yourlist,R.layout.item_product_grid); 
    mRecyclerView.setAdapter(mSampleAdapter); 

    mRecyclerView.setHasFixedSize(true); 

    final GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 
      2,        //number of columns 
      LinearLayoutManager.VERTICAL, // orientation 
      false);       //reverse layout 
    mRecyclerView.setLayoutManager(layoutManager); 

    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 
     @Override 
     public int getSpanSize(int position) { 

      // to show header and footer in full row 
      if(position==0 || position==(yourlist.size()+1)) 
       return layoutManager.getSpanCount(); 
      else 
       return 1; 
     } 
    }); 

    mRecyclerView.scrollToPosition(AppController.currentPosition); 

    mSampleAdapter.notifyDataSetChanged(); 

    // Scroll listener for RecyclerView to call load more products 
    mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { 

     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 

      int visibleItemCount = layoutManager.getChildCount(); 
      int totalItemCount = layoutManager.getItemCount(); 
      int firstVisibleItem = layoutManager.findFirstVisibleItemPosition(); 

      int lastInScreen = firstVisibleItem + visibleItemCount; 
      if ((lastInScreen >= totalItemCount) && !isLoading) { 
       //last item 
       // do something after last item like load more code or 
       // show No more items string 
       mSampleAdapter.setFooterData("NO More Items",View.INVISIBLE); 
      } 
      AppController.currentPosition = firstVisibleItem; 
     } 
    }); 

} 

// Adding to adapter as listview when list button clicked 
private void setProductListAdapter() { 
    mListViewTab.setVisibility(View.INVISIBLE); 
    mGridViewTab.setVisibility(View.VISIBLE); 

    mSampleAdapter = new SampleAdapter(YourActicity.this, yourlist,R.layout.item_product_list); 
    mRecyclerView.setAdapter(mSampleAdapter); 

    mRecyclerView.setHasFixedSize(true); 

    final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), 
      LinearLayoutManager.VERTICAL, // orientation 
      false);       //reverse layout 
    mRecyclerView.setLayoutManager(layoutManager); 

    mRecyclerView.scrollToPosition(AppController.currentPosition); 
    mSampleAdapter.notifyDataSetChanged(); 

    // Scroll listener for RecyclerView to call load more products 
    mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { 

     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 

      int visibleItemCount = layoutManager.getChildCount(); 
      int totalItemCount = layoutManager.getItemCount(); 
      int firstVisibleItem = layoutManager.findFirstVisibleItemPosition(); 

      int lastInScreen = firstVisibleItem + visibleItemCount; 
      if ((lastInScreen >= totalItemCount) && !isLoading) { 
       //last item 
       // do something after last item like load more code or 
       // show No more items string 
       mSampleAdapter.setFooterData("NO MOre Items",View.INVISIBLE); 
      } 
      AppController.currentPosition = firstVisibleItem; 
     } 
    }); 
} 

i Twoja aktywność musi implementować SampleAdapterInterface w działaniu, aby uzyskać oddzwonienie z adaptera. Zadzwoń do tych metod, gdy przełączasz przycisk z siatki na listę i odwrotnie.

Powiązane problemy