package com.ecollege.android.adapter;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.NotImplementedException;
import android.app.Activity;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.TextView;
import com.ecollege.android.R;
public class GroupedAdapter extends BaseAdapter {
public static final long STARTING_ITEM_ID = Long.MAX_VALUE - 1000;
protected ListAdapter baseAdapter;
protected Context context;
private ParentAdapterObserver baseObserver;
private List<GroupedDataItem> dataItems;
private boolean hasFooter;
private boolean hasHeader;
public GroupedAdapter(Context context, ListAdapter baseAdapter) {
this(context,baseAdapter,true,false);
}
public GroupedAdapter(Context context, ListAdapter baseAdapter, boolean hasHeader, boolean hasFooter) {
this.hasHeader = hasHeader;
this.hasFooter = hasFooter;
this.baseAdapter = baseAdapter;
this.context = context;
calculateHeadersAndFooters();
baseObserver = new ParentAdapterObserver(this);
baseAdapter.registerDataSetObserver(baseObserver);
}
public void update(ListAdapter baseAdapter) {
this.baseAdapter.unregisterDataSetObserver(baseObserver);
this.baseAdapter = baseAdapter;
this.baseAdapter.registerDataSetObserver(baseObserver);
this.notifyDataSetChanged();
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
calculateHeadersAndFooters();
}
protected void calculateHeadersAndFooters() {
long itemId = STARTING_ITEM_ID;
dataItems = new ArrayList<GroupedAdapter.GroupedDataItem>();
Object lastGroupId = null;
Object currentGroupId = null;
for (int i=0;i<baseAdapter.getCount();i++) {
currentGroupId = groupIdFunction(baseAdapter.getItem(i),i);
if (lastGroupId == null && hasHeader) {
dataItems.add(new GroupedDataItem(GroupedDataItemType.HEADER,currentGroupId, itemId));
itemId++;
} else if (currentGroupId != null && !currentGroupId.equals(lastGroupId)) {
if (hasFooter) {
dataItems.add(new GroupedDataItem(GroupedDataItemType.FOOTER,currentGroupId, itemId));
itemId++;
}
if (hasHeader) {
dataItems.add(new GroupedDataItem(GroupedDataItemType.HEADER,currentGroupId, itemId));
itemId++;
}
}
dataItems.add(new GroupedDataItem(i));
lastGroupId = currentGroupId;
}
if (hasFooter && currentGroupId != null) {
dataItems.add(new GroupedDataItem(GroupedDataItemType.FOOTER,currentGroupId, itemId));
itemId++;
}
}
protected Object groupIdFunction(Object item, int position) {
//override in subclass
throw new NotImplementedException();
}
public int getCount() {
return dataItems.size();
}
public Object getItem(int position) {
GroupedDataItem item = dataItems.get(position);
if (item.getItemType() != GroupedDataItemType.REGULAR_ITEM) {
return item;
} else {
return baseAdapter.getItem(item.getOriginalPosition());
}
}
public long getItemId(int position) {
GroupedDataItem item = dataItems.get(position);
if (item.getItemType() != GroupedDataItemType.REGULAR_ITEM) {
return item.getItemId();
} else {
return baseAdapter.getItemId(item.getOriginalPosition());
}
}
protected int loadMoreViewType() {
return (baseAdapter.getViewTypeCount() - 1) + 1;
}
protected int loadingViewType() {
return (baseAdapter.getViewTypeCount() - 1) + 2;
}
public int getItemViewType(int position) {
GroupedDataItem item = dataItems.get(position);
if (item.getItemType() == GroupedDataItemType.HEADER) {
return baseAdapter.getViewTypeCount();
} else if (item.getItemType() == GroupedDataItemType.FOOTER) {
return hasHeader ? baseAdapter.getViewTypeCount() + 1 : baseAdapter.getViewTypeCount();
} else {
return baseAdapter.getItemViewType(item.getOriginalPosition());
}
}
public View getLoadMoreView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = ((Activity)context).getLayoutInflater().inflate(R.layout.load_more_item, null);
}
return convertView;
}
public View getLoadingView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = ((Activity)context).getLayoutInflater().inflate(R.layout.loading_item, null);
}
return convertView;
}
//optionally override in subclass
public View getHeaderView(int position, View convertView, ViewGroup parent, Object groupId) {
ViewHolder holder;
if (convertView == null) {
convertView = ((Activity)context).getLayoutInflater().inflate(R.layout.list_header_item, null);
holder = new ViewHolder();
holder.headerLabelText = (TextView) convertView.findViewById(R.id.header_label_text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.headerLabelText.setText(groupId.toString());
return convertView;
}
//must override in subclass
public View getFooterView(int position, View convertView, ViewGroup parent, Object groupId) {
throw new NotImplementedException();
}
public View getView(int position, View convertView, ViewGroup parent) {
GroupedDataItem item = dataItems.get(position);
if (item.getItemType() == GroupedDataItemType.HEADER) {
return getHeaderView(position, convertView, parent, item.getGroupId());
} else if (item.getItemType() == GroupedDataItemType.FOOTER) {
return getFooterView(position, convertView, parent, item.getGroupId());
} else {
return baseAdapter.getView(item.getOriginalPosition(),convertView,parent);
}
}
public int getViewTypeCount() {
int result = baseAdapter.getViewTypeCount();
if (hasHeader) result++;
if (hasFooter) result++;
return result;
}
public void registerDataSetObserver(DataSetObserver observer) {
super.registerDataSetObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
super.unregisterDataSetObserver(observer);
}
public boolean hasStableIds() {
return baseAdapter.hasStableIds();
}
public boolean isEmpty() {
return baseAdapter.isEmpty();
}
public boolean areAllItemsEnabled() {
return false;
}
public boolean isEnabled(int position) {
GroupedDataItem item = dataItems.get(position);
if (item.getItemType() != GroupedDataItemType.REGULAR_ITEM) {
return false;
} else {
return baseAdapter.isEnabled(item.getOriginalPosition());
}
}
private static class ViewHolder {
TextView headerLabelText;
}
public enum GroupedDataItemType {
HEADER,
REGULAR_ITEM,
FOOTER
}
public class GroupedDataItem {
private GroupedDataItemType itemType;
private Object groupId;
private long itemId = -1;
private int originalPosition = -1;
public GroupedDataItem(GroupedDataItemType itemType, Object groupId, long itemId) {
this.itemType = itemType; //HEADER or FOOTER
this.groupId = groupId;
this.itemId = itemId;
}
public GroupedDataItem(int originalIndex) {
this.originalPosition = originalIndex;
this.itemType = GroupedDataItemType.REGULAR_ITEM;
}
public GroupedDataItemType getItemType() {
return itemType;
}
public Object getGroupId() {
return groupId;
}
public int getOriginalPosition() {
return originalPosition;
}
public long getItemId() {
return itemId;
}
}
}