2015-07-21 62 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以從適配器獲取回調。 調用這些方法時,切換按鈕從網格到列表,反之亦然

相關問題