Created
August 26, 2015 19:27
-
-
Save chantellosejo/ecefae62053af5f3e2b5 to your computer and use it in GitHub Desktop.
This adapter wraps multiple adapters with different object types for use with a recyclerview.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.support.v7.widget.RecyclerView; | |
import android.util.SparseArray; | |
import android.view.ViewGroup; | |
/** | |
* Created by Chantell Osejo on 8/7/15. | |
* This adapter wraps multiple adapters with different object types for use with a recyclerview. | |
* Copyright (C) 2015 Chantell Osejo | |
* | |
* This program is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 3 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program. If not, see <http://www.gnu.org/licenses/> | |
*/ | |
public class MultiObjectAdapterRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { | |
private RecyclerView.Adapter[] containedAdapters; | |
// In onCreateViewHolder, we are only given view type. This does not map well if, | |
// as is the case for this adapter, multiple adapters are involved, since adapters' view types | |
// are not guaranteed to be unique (one adapter could use the same "viewType" int as another). | |
// This means that we can't just return the view type specified by the adapter that coordinates with the position in question, | |
// but we also can't return the index of the adapter, either (because this means the actual view type would be lost, although | |
// we could then retrieve the adapter in onCreateViewHolder using the viewType as the index in our list of containedAdapters). | |
// So this object, AdapterItemViewType, is simply a container object that pairs an adapter with a view type. | |
// This object is then added to this SparseArray, which guarantees it has a unique key, which will become the "viewType" | |
// we receive in onCreateViewHolder. We'll use that key to retrieve the AdapterItemViewType object, which will then point | |
// to both the adapter and the actual viewType we care about. | |
private SparseArray<AdapterItemViewType> adapterItemViewTypes = new SparseArray<>(); | |
class AdapterItemViewType { | |
public RecyclerView.Adapter adapter; | |
public int adapterViewType; | |
public AdapterItemViewType(RecyclerView.Adapter adapter, int viewType) { | |
this.adapter = adapter; | |
this.adapterViewType = viewType; | |
} | |
} | |
public MultiObjectAdapterRecyclerViewAdapter(RecyclerView.Adapter[] adapterList) { | |
containedAdapters = adapterList; | |
for (RecyclerView.Adapter adapter : containedAdapters) { | |
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { | |
@Override | |
public void onChanged() { | |
notifyDataSetChanged(); | |
} | |
}); | |
} | |
} | |
@Override | |
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
AdapterItemViewType adapterItemViewType = adapterItemViewTypes.get(viewType); | |
return adapterItemViewType.adapter.onCreateViewHolder(parent, adapterItemViewType.adapterViewType); | |
} | |
@Override | |
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { | |
//Figure out the right adapter that this should be handled by | |
getAdapterForPosition(position).onBindViewHolder(holder, getRelativePositionInAdapter(position)); | |
} | |
public RecyclerView.Adapter getAdapterForPosition(int position) { | |
for (RecyclerView.Adapter adapter : containedAdapters) { | |
if (adapter.getItemCount() > position) { | |
return adapter; | |
} | |
position -= adapter.getItemCount(); | |
} | |
throw new ArrayIndexOutOfBoundsException(position); | |
} | |
private int getRelativePositionInAdapter(int position) { | |
for (int i = 0; i < containedAdapters.length; i++) { | |
RecyclerView.Adapter adapter = containedAdapters[i]; | |
if (adapter.getItemCount() > position) { | |
return position; | |
} | |
position -= adapter.getItemCount(); | |
} | |
throw new ArrayIndexOutOfBoundsException(position); | |
} | |
@Override | |
public int getItemViewType(int position) { | |
RecyclerView.Adapter adapter = getAdapterForPosition(position); | |
AdapterItemViewType adapterItemViewType = new AdapterItemViewType(adapter, adapter.getItemViewType(getRelativePositionInAdapter(position))); | |
if (adapterItemViewTypes.size() > position && adapterItemViewTypes.get(position) != null) { | |
adapterItemViewTypes.put(position, adapterItemViewType); | |
} else { | |
adapterItemViewTypes.put(position, adapterItemViewType); | |
} | |
return position; | |
} | |
@Override | |
public int getItemCount() { | |
int count = 0; | |
for (RecyclerView.Adapter adapter : containedAdapters) { | |
count += adapter.getItemCount(); | |
} | |
return count; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment