diegocarloslima / FloatingGroupExpandableListView

An open source Android library that provides a floating group view at the top of the ExpandableListView
Apache License 2.0
372 stars 136 forks source link

How to get fixed headers irrespective of the child view container height #22

Closed navaneet closed 10 years ago

navaneet commented 10 years ago

First thank you for this awesome library :)

I am using three group headers... everything runs fine as long as the middle group header have limited number in number of items. However when the number of items within the second header is large, the other headers are pushed out of the viewing container although we can still scroll and go to that header but, that is not the desired behaviour I was looking for.

Is there a way I can make all the headers stick to their place?

diegocarloslima commented 10 years ago

Hello @navaneet, I also saw your email, but I'm answering here so others can benefit from this discussion. Currently, the lib only supports one floating group at a time. If I understood your correctly, you want the last group header to float over any view, even if its a child that doesn't belongs to that group (can be a child from the 2nd group). Unfortunately, that is not a really relevant request to this lib project, once a group shouldn't float above other group views. I suggest you to take a look on FloatingGroupExpandableListView to see how I measure, layout and draw the current floating group view. Once you understand how it works and with some more calculation, you will be able to position more than one floating view in your ExpandableListView =) .

navaneet commented 10 years ago

Thanks for the quick reply :)

I will try the code in the FloatingGroupExpandableListView

By the way can u please give me some pointers to the logic that your are doing to get the floating group headers, something to look out for?

diegocarloslima commented 10 years ago

Hey @navaneet , sorry for the delay =( well the main logic is inside the createFloatingGroupView() method. Mainly, you will have to take a look on these snippets: 1) Here is where I check if the current floating group is still partially visible on screen, that way i need to set the child of the ExpandableListView as invisible:

    final int floatingGroupFlatPosition = getFlatListPosition(getPackedPositionForGroup(mFloatingGroupPosition));
    final int floatingGroupListPosition = floatingGroupFlatPosition - position;

    if(floatingGroupListPosition >= 0 && floatingGroupListPosition < getChildCount()) {
        final View currentGroupView = getChildAt(floatingGroupListPosition);

        if(currentGroupView.getTop() >= getPaddingTop()) {
            return;
        } else if(currentGroupView.getTop() < getPaddingTop() && currentGroupView.getVisibility() == View.VISIBLE) {
            currentGroupView.setVisibility(View.INVISIBLE);
            currentGroupView.setTag(R.id.fgelv_tag_changed_visibility, true);
        }
    }

2) Here is where i measure the floating group view and I check the position of the next group view in order to proper position the floating group, giving the sensation that the current floating group is being pushed up by the next group view when scrolling. In your case, you will need to adapt this part to position each of your group views above some specific point (that will depend of your logic):

    final int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), params.width);
    final int paramsHeight = params.height;
    int childHeightSpec;
    if(paramsHeight > 0) {
        childHeightSpec = MeasureSpec.makeMeasureSpec(paramsHeight, MeasureSpec.EXACTLY);
    } else {
        childHeightSpec = MeasureSpec.makeMeasureSpec(0 , MeasureSpec.UNSPECIFIED);
    }

    mFloatingGroupView.measure(childWidthSpec, childHeightSpec);

    int floatingGroupScrollY = 0;

    final int nextGroupFlatPosition = getFlatListPosition(getPackedPositionForGroup(mFloatingGroupPosition + 1));
    final int nextGroupListPosition = nextGroupFlatPosition - position;

    if(nextGroupListPosition >= 0 && nextGroupListPosition < getChildCount()) {
        final View nextGroupView = getChildAt(nextGroupListPosition);

        if(nextGroupView != null && nextGroupView.getTop() < getPaddingTop() + mFloatingGroupView.getMeasuredHeight() + getDividerHeight()) {
            floatingGroupScrollY = nextGroupView.getTop() - (getPaddingTop() + mFloatingGroupView.getMeasuredHeight() + getDividerHeight());
        }
    }

    final int left = getPaddingLeft();
    final int top = getPaddingTop() + floatingGroupScrollY;
    final int right = left + mFloatingGroupView.getMeasuredWidth();
    final int bottom = top + mFloatingGroupView.getMeasuredHeight();
    mFloatingGroupView.layout(left, top, right, bottom);

    mFloatingGroupScrollY = floatingGroupScrollY;
    if(mOnScrollFloatingGroupListener != null) {
        mOnScrollFloatingGroupListener.onScrollFloatingGroupListener(mFloatingGroupView, mFloatingGroupScrollY);
    }
}
navaneet commented 10 years ago

Thanks :)