How do I use the ResourceCursorTreeAdapter with the following constructor?
ResourceCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout, int expandedGroupLayout, int childLayout)
I'm trying to use a it as follows:
_resultsCursorTreeAdapter = new ResourceCursorTreeAdapter(_resultsList.getContext(), _dbAdapter.getAllGroups(),
R.layout.timing_group_view_collapsed, R.layout.timing_group_view_expanded, R.layout.timing_result_view) {
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
// Given the group, we return a cursor for all the children within that group
int groupId = groupCursor.getInt(0);
Cursor childCursor = _dbAdapter.getContractionsForGroup(groupId);
return childCursor;
}
@Override
protected void bindGroupView(View groupView, Context context, Cursor cursor,
boolean isExpanded) {
TimingGroupView timingGroupItem = null;
if(groupView instanceof LinearLayout){
Log.i("TimingGroupView", "Has Header");
LinearLayout layout = (LinearLayout)groupView;
timingGroupItem = (TimingGroupView) layout.getChildAt(0);
} else{
Log.i("TimingGroupView", "No Header");
timingGroupItem = (TimingGroupView) groupView;
}
...
If the group node is expanded, I want the group node to include the header for a table which each row is held in a child node. timing_group_view_expanded.xml and timing_group_view_collapsed.xml are shown at the bottom of this question. For some reason, the group_view_expanded is never used whether the group nodes are expanded or collapsed. Am I using this wrong? Has anyone else been able to get ResourceCursorTreeAdapter with this constructor to work?
timing_group_view_expanded.xml is as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/timing_group_view"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/header_timing_color">
<com.contractiontracker.TimingGroupView
android:id="@+id/timing_group_item" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_marginLeft="30px" android:padding="10dp"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:background="@color/header_timing_color"
android:textColor="@color/text_color"/>
<com.contractiontracker.RowLayout android:id="@+id/timing_group_view"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/header_color" android:textColor="@color/text_color">
<TextView android:id="@+id/interval_header"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Interval" android:layout_weight="1"
android:layout_gravity="left|bottom" android:gravity="center"
android:textColor="@color/text_color">
</TextView>
<TextView android:id="@+id/duration_header"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Duration" android:layout_weight="1"
android:layout_gravity="center_horizontal|bottom" android:gravity="center"
android:textColor="@color/text_color"
>
</TextView>
<TextView android:id="@+id/intensity_header"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Intensity" android:layout_weight="1"
android:layout_gravity="right|bottom" android:gravity="center"
android:textColor="@color/text_color"
>
</TextView>
</com.contractiontracker.RowLayout>
</LinearLayout>
timing_group_view_collapsed.xml looks like the following:
<?xml version="1.0" encoding="utf-8"?>
<com.contractiontracker.TimingGroupView
android:id="@+id/timing_group_item"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50px"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="@color/text_color"
android:fadingEdge="vertical"/>
The problem is that ResourceCursorTreeAdapter
only creates the correct layouts on creation of a view. So if a group gets collapsed or expanded the newGroupView()
is not called again and therefore the different group layouts passed into the constructor are not used as expected.
Same problem exists with the child layouts when using different ones for normal and last child. It happens there without even changing the data! After re-expanding a group the first one had the footer layout and vice-versa. Totally random and not based on position in the list.
As Aleksander O showed in his example, one can fix this by always call newGroupView()
in the getGroupView
method (and the getChildView
respectively if different layouts are used for that).
To avoid always create new views, I tried a different approach that works for my case:
Store those view-ids as int members of my Adapter:
// Get the view ids for comparison
View view = newGroupView(mContext, null, false, null);
mCollapsedGroupLayoutViewId = view.getId();
view = newGroupView(mContext, null, true, null);
mExpandedGroupLayoutViewId = view.getId();
view = newChildView(mContext, null, false, null);
mChildLayoutViewId = view.getId();
view = newChildView(mContext, null, true, null);
mLastChildLayoutViewId = view.getId();
Implementation of getGroupView (and analog with getChildView):
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
Cursor cursor = getGroup(groupPosition);
if (cursor == null) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
View v;
if (convertView == null
|| (isExpanded && convertView.getId() == mCollapsedGroupLayoutViewId)
|| (!isExpanded && convertView.getId() == mExpandedGroupLayoutViewId)) {
v = newGroupView(mContext, cursor, isExpanded, parent);
}
else {
v = convertView;
}
bindGroupView(v, mContext, cursor, isExpanded);
return v;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With