2015-07-21 4 views
6

Я разрабатываю приложение, которое в значительной степени зависит от использования RecyclerView.Как использовать тот же адаптер RecyclerView для разных макетов

Мне действительно нужно знать, как использовать тот же RecyclerView для разных макетов элементов. Пример планировки являются:

1) Элемент списка с именем и описанием

2) Элемент списка с изображением и именем

Вы можете видеть, что они похожи, но с небольшим изменения в макете.

Заранее благодарен!

+0

Вам нужно предоставить более подробную информацию о вашем приложении - в противном случае трудно дать рекомендацию – ligi

ответ

4

Поскольку элемент recyclerview в xml не зависит от типа элементов, которые вы будете накачивать в нем, вы можете продолжить использование одного и того же файла макета вида ресайклеров для трех фрагментов.

Что касается адаптеров, то ваши списки кажутся однородными (т. Е. Один вид вида). Лучше всего использовать три разных адаптера для каждого случая. Вы можете настроить конструктор, добавить пользовательские вспомогательные методы для каждого типа адаптера в соответствии с вашим удобством.

Теперь, если у вас есть неоднородный список, вам придется переопределить getItemViewType() в адаптере и использовать надлежащим образ в onCreateViewHolder() и onBindViewHolder()

Надеется, что это помогает! :)

3

Я столкнулся с подобной ситуацией, и вот модель, которой я следовал.

Прежде всего, Фрагмент макета.

Файл фрагмента фрагмента не изменится для всех 3 фрагментов (в основном это похоже на фрагмент списка), поэтому я создал файл шаблона для фрагмента списка.

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> 

Теперь фрагмент кода:

В моем случае все 3 фрагмента делает почти те же вещи (получить вид ресайклера, получить адаптер, украшение вида ресайклера и еще несколько операций и т.д.).

Создал AbstrctFragment, который расширяет фрагмент и отменяет onCreate onAttach onDestroy и т. Д. Поскольку только тип использования recycliewiew данных и адаптеры для пересылки данных в recycelrview будут меняться для каждого фрагмента, создайте абстрактную функцию для получения атрибутов и templatize данных. Каждый из трех фрагментов будет получен из этого 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 и любые общие членские функции и переменные-члены, которые поступают для каждого фрагмента.

RecyclerView файлы макета. Поскольку все они различны в макете, очевидно, они должны быть разными.

RecyclerViewAdapters: Опять же здесь общий код будет деклараций членов, CreateViewHolder (здесь только макет изменения названия отдыха весь код такой же) и любой другой функции, все эти адаптеры будут совместно. (что-то вроде фильтрующих элементов списка).

подобно тому, как мы это делали для фрагментов, вы можете сохранить это в AbstractRecyclerViewAdapter и сделать bindViewholder и т.д. как абстрактные функции и имеют 3 различных recyclerAdapters, которые могли бы извлечь из этого 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

Это не подкласс RecyclerView.Adapter. OP хочет помочь с RecyclerView конкретно :) –

0

слишком поздно, но, может быть полезным для кого-то нуждающемуся разработчика Ваш адаптер должен выглядеть следующим образом, также вы можете добавить заголовок и нижний колонтитулы, используя этот образец

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

в вашей деятельности

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

и ваша деятельность должна реализовать SampleAdapterInterface в действии для получения обратного вызова от адаптера. Вызовите эти методы при переключении кнопки из сетки в список и наоборот

Смежные вопросы