2015-07-21 65 views
6

我正在开发一个严重依赖于RecyclerView的应用程序。如何为不同的布局使用相同的RecyclerView适配器

我真的需要知道如何针对不同的项目布局使用相同的RecyclerView。布局的一个例子是:

1)的名称和描述列表项

2)与图像和名称的列表项

你可以看到它们是相似的,但有轻微更改布局。

提前致谢!

+0

您需要提供有关您的应用的更多细节 - 否则很难给出推荐 – ligi

回答

4

由于XML的recyclerview项目不依赖于那种你会在它膨胀的项目,你可以继续使用相同的回收视图布局文件的三个片段。

至于适配器,您的列表似乎是同质的(即单一类型的查看项目)。最好的做法是为每种情况使用3种不同的适配器。您可以自定义构造函数,为您的方便添加每种适配器的自定义帮助器方法。

现在,如果你有一个异构的列表中,你将不得不覆盖适配器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个片段做几乎同样的东西(得到回收观点,得到适配器,回收视图装饰和一些更多的操作等)。

创建延伸片段和overrided的onCreate onAttach的onDestroy等。由于只类型数据recyclerview消耗和适配器的将数据推至recycelrview将针对每个片段而改变,创建抽象函数getAdapter和模板化数据的AbstrctFragment。这三个片段中的每一个都将从这个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以及任何常见的memberfunctions和每个片段的成员变量。

现在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以从适配器获取回调。 调用这些方法时,切换按钮从网格到列表,反之亦然

相关问题