我正在開發一個嚴重依賴於RecyclerView的應用程序。如何爲不同的佈局使用相同的RecyclerView適配器
我真的需要知道如何針對不同的項目佈局使用相同的RecyclerView。佈局的一個例子是:
1)的名稱和描述列表項
2)與圖像和名稱的列表項
你可以看到它們是相似的,但有輕微更改佈局。
提前致謝!
我正在開發一個嚴重依賴於RecyclerView的應用程序。如何爲不同的佈局使用相同的RecyclerView適配器
我真的需要知道如何針對不同的項目佈局使用相同的RecyclerView。佈局的一個例子是:
1)的名稱和描述列表項
2)與圖像和名稱的列表項
你可以看到它們是相似的,但有輕微更改佈局。
提前致謝!
由於XML的recyclerview項目不依賴於那種你會在它膨脹的項目,你可以繼續使用相同的回收視圖佈局文件的三個片段。
至於適配器,您的列表似乎是同質的(即單一類型的查看項目)。最好的做法是爲每種情況使用3種不同的適配器。您可以自定義構造函數,爲您的方便添加每種適配器的自定義幫助器方法。
現在,如果你有一個異構的列表中,你將不得不覆蓋適配器getItemViewType()
和onCreateViewHolder()
和onBindViewHolder()
希望這有助於適當地使用這個! :)
我碰到類似的情況,這裏是我遵循的模式。
首先,片段佈局文件。
片段佈局文件是不會更改所有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派生..
//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;
}
這不是一個RecyclerView.Adapter子類。 OP想要特別幫助RecyclerView :) –
爲時已晚,但是,可能是有人需要幫助開發商 有益的適配器應該是這樣的,你也可以在你的活動使用此示例
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以從適配器獲取回調。 調用這些方法時,切換按鈕從網格到列表,反之亦然
您需要提供有關您的應用的更多細節 - 否則很難給出推薦 – ligi