package gueei.binding.collections;
import java.util.ArrayList;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
/**
* Provide a nested relationship between adapters
* @author andy
*
*/
public class CombinedAdapter extends BaseAdapter implements LazyLoadAdapter{
private ArrayList<TranslatedAdapter> mTranslated = new ArrayList<TranslatedAdapter>();
private DataSetObserver observer = new DataSetObserver(){
@Override
public void onChanged() {
super.onChanged();
calculateTranslation();
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
super.onInvalidated();
notifyDataSetInvalidated();
calculateTranslation();
}
};
public void addAdapter(Adapter[] adapter){
for (int i=0; i<adapter.length; i++){
mTranslated.add(new TranslatedAdapter(adapter[i]));
adapter[i].registerDataSetObserver(observer);
}
calculateTranslation();
notifyDataSetChanged();
}
/**
* Add a new adapter to combined adapter, whenever a new adapter is added, the
* List will be invalidated.
* @param adapter
*/
public void addAdapter(Adapter adapter){
mTranslated.add(new TranslatedAdapter(adapter));
adapter.registerDataSetObserver(observer);
calculateTranslation();
notifyDataSetChanged();
}
public void remvoeAdapter(Adapter adapter){
for(int i=0; i<mTranslated.size(); i++){
if (mTranslated.get(i).adapter.equals(adapter)){
mTranslated.remove(i);
adapter.unregisterDataSetObserver(observer);
break;
}
}
calculateTranslation();
notifyDataSetChanged();
}
private int mItemCount, mItemTypeCount;
private void calculateTranslation(){
int pos = 0;
int typeOffset = 0;
mItemTypeCount = 0;
mItemCount = 0;
for(TranslatedAdapter p: mTranslated){
p.offset = pos;
p.itemTypeOffset = typeOffset;
pos += p.adapter.getCount();
typeOffset += p.adapter.getViewTypeCount();
}
mItemCount = pos;
mItemTypeCount = typeOffset;
}
public int getCount() {
return mItemCount;
}
public Object getItem(int position) {
TranslatedAdapter adapter = getAdapterAt(position);
if (adapter!=null)
return adapter.adapter.getItem(position - adapter.offset);
return null;
}
private TranslatedAdapter getAdapterAt(int position){
int length = mTranslated.size();
TranslatedAdapter adapter;
for (int i=0; i<length; i++){
adapter = mTranslated.get(i);
if(position >= adapter.offset + adapter.adapter.getCount())
continue;
else
return adapter;
}
return null;
}
public long getItemId(int position) {
TranslatedAdapter adapter = getAdapterAt(position);
if (adapter!=null)
return adapter.adapter.getItemId(position - adapter.offset);
return -1;
}
public View getView(int position, View convertView, ViewGroup parent) {
TranslatedAdapter adapter = getAdapterAt(position);
if (mHelper!=null){
mHelper.onGetView(position);
}
if (adapter!=null)
return adapter.adapter.getView(position - adapter.offset, convertView, parent);
return null;
}
@Override
public int getItemViewType(int position) {
TranslatedAdapter adapter = getAdapterAt(position);
if (adapter!=null)
return adapter.itemTypeOffset + adapter.adapter.getItemViewType(position - adapter.offset);
return BaseAdapter.IGNORE_ITEM_VIEW_TYPE;
}
@Override
public int getViewTypeCount() {
return mItemTypeCount;
}
private class TranslatedAdapter{
public int offset, itemTypeOffset;
public final Adapter adapter;
public TranslatedAdapter(Adapter adapter){
this.adapter =adapter;
}
}
private Mode mMode = Mode.LoadWhenStopped;
private LazyLoadRootAdapterHelper mHelper;
public void setRoot(AbsListView view) {
mHelper = new LazyLoadRootAdapterHelper(view, this, mMode);
}
public void setMode(Mode mode) {
if (mHelper!=null)
{
mHelper.setMode(mode);
}
mMode = mode;
}
public void onVisibleChildrenChanged(int first, int total) {
visibleChildrenChanged(first, total);
}
private void visibleChildrenChanged(int first, int total){
TranslatedAdapter adapter = getAdapterAt(first);
if (adapter==null) return;
int afirst = first - adapter.offset;
if (adapter.adapter.getCount() - afirst < total){
int atotal = adapter.adapter.getCount() - afirst;
if (adapter.adapter instanceof LazyLoadAdapter){
((LazyLoadAdapter)adapter.adapter).onVisibleChildrenChanged(afirst, atotal);
}
visibleChildrenChanged(first+atotal, total-atotal);
}else{
if (adapter.adapter instanceof LazyLoadAdapter){
((LazyLoadAdapter)adapter.adapter).onVisibleChildrenChanged(afirst, total);
}
}
}
@Override
public boolean areAllItemsEnabled() {
for(TranslatedAdapter ta: mTranslated){
Adapter adapter = ta.adapter;
if (adapter instanceof ListAdapter){
if (!((ListAdapter)adapter).areAllItemsEnabled())
return false;
}
}
return true;
}
@Override
public boolean isEnabled(int position) {
TranslatedAdapter ta = getAdapterAt(position);
if (ta.adapter instanceof ListAdapter)
return ((ListAdapter)ta.adapter).isEnabled(position - ta.offset);
return true;
}
}