package com.kemallette.MultiChoiceExpandableList;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ExpandableListAdapter;
public class MultiChoiceExpandableAdapter extends
BaseExpandableListAdapter implements
MultiChoiceAdapterWrapper,
OnCheckedChangeListener{
// TODO: To implement 'checking' a whole list item, instead of using a
// compound button,
// will need to implement checkable list item views with custom listener
// interface
private static final String TAG = "MultiChoiceExpandableAdapter";
static final String GROUP_POSITION = "groupPosition",
CHILD_POSITION = "childPosition",
GROUP_ID = "groupId",
CHILD_ID = "childId",
IS_GROUP = "isGroup";
/**
* Listens to the client adapter for data changes.
*/
protected class MyDataObserver extends
DataSetObserver{
// TODO: will probably need to use these to fully implement choice for
// unstableIds
/*
* Client adapter data has changed
*
* Called when the contents of the data set have changed. The recipient
* will obtain the new contents the next time it queries the data set.
*/
@Override
public void onChanged(){
mDataSetObservable.notifyChanged();
}
/*
* Called when the data set is no longer valid and cannot be queried
* again, such as when the data set has been closed.
*/
@Override
public void onInvalidated(){
mDataSetObservable.notifyInvalidated();
}
}
protected static class Holder{
Bundle mData = new Bundle();
CompoundButton mBox;
void tagGroupBoxData(final int groupPosition, final long groupId){
mData.putInt( GROUP_POSITION,
groupPosition);
mData.putLong( GROUP_ID,
groupId);
mData.putBoolean( IS_GROUP,
true);
mBox.setTag(R.id.checkable_tag_key,
mData);
}
void tagChildBoxData(final int groupPosition,
final int childPosition,
final long groupId,
final long childId){
mData.putInt( GROUP_POSITION,
groupPosition);
mData.putInt( CHILD_POSITION,
childPosition);
mData.putLong( GROUP_ID,
groupId);
mData.putLong( CHILD_ID,
childId);
mData.putBoolean( IS_GROUP,
false);
mBox.setTag(R.id.checkable_tag_key,
mData);
}
Bundle getBoxData(){
return (Bundle) mBox.getTag(R.id.checkable_tag_key);
}
}
boolean ignoreCheckChange = false;
boolean isChoiceOn = true;
private final DataSetObservable mDataSetObservable = new DataSetObservable();
private final MyDataObserver mDataObserver = new MyDataObserver();
private ExpandableListAdapter mWrappedAdapter;
private final MultiCheckable mList;
public MultiChoiceExpandableAdapter(final ExpandableListAdapter mWrappedAdapter,
final MultiCheckable mList){
this.mWrappedAdapter = mWrappedAdapter;
this.mList = mList;
isChoiceOn = mList.isChoiceOn();
registerClientDataSetObserver(mDataObserver);
}
void enableChoice(){
isChoiceOn = true;
}
void disableChoice(){
isChoiceOn = false;
}
boolean isChoiceOn(){
return isChoiceOn;
}
@Override
public void onCheckedChanged(final CompoundButton mButton,
final boolean isChecked){
if (!ignoreCheckChange
&& isChoiceOn()){
Bundle mCheckData;
if (mButton.getTag(R.id.checkable_tag_key) != null){
mCheckData = (Bundle) mButton.getTag(R.id.checkable_tag_key);
if (!mCheckData.isEmpty()
&& mCheckData.containsKey(IS_GROUP))
if (mCheckData.getBoolean(IS_GROUP))
mList.onGroupCheckChange( mButton,
mCheckData.getInt(GROUP_POSITION),
mCheckData.getLong(GROUP_ID),
isChecked);
else
mList.onChildCheckChange( mButton,
mCheckData.getInt(GROUP_POSITION),
mCheckData.getLong(GROUP_ID),
mCheckData.getInt(CHILD_POSITION),
mCheckData.getLong(CHILD_ID),
isChecked);
}else
Log.e( TAG,
"onCheckedChange mButton didn't have any tag data :( ");
}
}
@Override
public ExpandableListAdapter getWrappedAdapter(){
return mWrappedAdapter;
}
public void setWrappedAdapter(final ExpandableListAdapter mClientAdapter){
mWrappedAdapter = mClientAdapter;
}
@Override
public View getGroupView(final int groupPosition, final boolean isExpanded,
final View convertView, final ViewGroup parent){
final View groupView = mWrappedAdapter.getGroupView(groupPosition,
isExpanded,
convertView,
parent);
if (groupView == null)
Log.e( TAG,
"Users adapter returned null for getGroupView");
Holder mGroupHolder;
if (groupView.getTag(R.id.view_holder_key) == null){
mGroupHolder = new Holder();
mGroupHolder.mBox = (CheckBox) groupView
.findViewById(android.R.id.checkbox);
mGroupHolder.mBox.setOnCheckedChangeListener(this);
groupView.setTag( R.id.view_holder_key,
mGroupHolder);
}else
mGroupHolder = (Holder) groupView.getTag(R.id.view_holder_key);
mGroupHolder.tagGroupBoxData( groupPosition,
getGroupId(groupPosition));
if (isChoiceOn
&& mList.getGroupChoiceMode() != MultiCheckable.CHECK_MODE_NONE){
mGroupHolder.mBox.setVisibility(View.VISIBLE);
ignoreCheckChange = true;
mGroupHolder.mBox.setChecked(mList.isGroupChecked(groupPosition));
ignoreCheckChange = false;
}else
// if choice mode isn't on or CHECK_MODE_NONE, we need to hide
// checkable views
mGroupHolder.mBox.setVisibility(View.INVISIBLE);
return groupView;
}
@Override
public View getChildView(final int groupPosition,
final int childPosition,
final boolean isLastChild,
final View convertView,
final ViewGroup parent){
final View childView = mWrappedAdapter.getChildView(groupPosition,
childPosition,
isLastChild,
convertView,
parent);
if (childView == null)
Log.e( TAG,
"Users adapter returned null for getChildView");
Holder mChildHolder;
if (childView.getTag(R.id.view_holder_key) == null){
mChildHolder = new Holder();
mChildHolder.mBox = (CheckBox) childView
.findViewById(android.R.id.checkbox);
mChildHolder.mBox.setOnCheckedChangeListener(this);
childView.setTag( R.id.view_holder_key,
mChildHolder);
}else
mChildHolder = (Holder) childView.getTag(R.id.view_holder_key);
mChildHolder.tagChildBoxData( groupPosition,
childPosition,
getGroupId(groupPosition),
getChildId( groupPosition,
childPosition));
if (isChoiceOn
&& mList.getChildChoiceMode() != MultiCheckable.CHECK_MODE_NONE){
mChildHolder.mBox.setVisibility(View.VISIBLE);
ignoreCheckChange = true;
mChildHolder.mBox.setChecked(mList.isChildChecked( groupPosition,
childPosition));
ignoreCheckChange = false;
}else
// if choice mode isn't on or CHECK_MODE_NONE, we need to hide
// checkable views
mChildHolder.mBox.setVisibility(View.INVISIBLE);
return childView;
}
@Override
public void registerDataSetObserver(final DataSetObserver mObserver){
mDataSetObservable.registerObserver(mObserver);
}
@Override
public void unregisterDataSetObserver(final DataSetObserver mObserver){
mDataSetObservable.unregisterObserver(mObserver);
}
/*********************************************************************
* Delegates to client's adapter (mWrappedAdapter)
**********************************************************************/
@Override
public boolean areAllItemsEnabled(){
return mWrappedAdapter.areAllItemsEnabled();
}
@Override
public Object getChild(final int groupPosition, final int childPosition){
return mWrappedAdapter.getChild(groupPosition,
childPosition);
}
@Override
public long getChildId(final int groupPosition, final int childPosition){
return mWrappedAdapter.getChildId( groupPosition,
childPosition);
}
@Override
public int getChildrenCount(final int groupPosition){
return mWrappedAdapter.getChildrenCount(groupPosition);
}
@Override
public long getCombinedChildId(final long groupId, final long childId){
return mWrappedAdapter.getCombinedChildId( groupId,
childId);
}
@Override
public long getCombinedGroupId(final long arg0){
return mWrappedAdapter.getCombinedGroupId(arg0);
}
@Override
public Object getGroup(final int groupPosition){
return mWrappedAdapter.getGroup(groupPosition);
}
@Override
public int getGroupCount(){
return mWrappedAdapter.getGroupCount();
}
@Override
public long getGroupId(final int groupPosition){
return mWrappedAdapter.getGroupId(groupPosition);
}
@Override
public boolean hasStableIds(){
return mWrappedAdapter.hasStableIds();
}
@Override
public boolean isChildSelectable(final int groupPosition,
final int childPosition){
return mWrappedAdapter.isChildSelectable( groupPosition,
childPosition);
}
@Override
public boolean isEmpty(){
return mWrappedAdapter.isEmpty();
}
@Override
public void onGroupCollapsed(final int groupPosition){
mWrappedAdapter.onGroupCollapsed(groupPosition);
}
@Override
public void onGroupExpanded(final int groupPosition){
mWrappedAdapter.onGroupExpanded(groupPosition);
}
private void registerClientDataSetObserver(final DataSetObserver mObserver){
mWrappedAdapter.registerDataSetObserver(mObserver);
}
private void
unregisterClientDataSetObserver(final DataSetObserver mObserver){
mWrappedAdapter.unregisterDataSetObserver(mObserver);
}
}