5

Adding enterAlways to the scroll flags of the Cheesesquare demo:

<android.support.design.widget.CollapsingToolbarLayout
    android:id="@+id/collapsing_toolbar"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    app:contentScrim="?attr/colorPrimary"
    app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlways">

results in a wrong layout:

enter image description here

During scrolling down, the header comes in correctly but it doesn't stop in the correct position. Scrolling further displaces the parts: the backdrop image appears in the wrong position and the toolbar becomes invisible because of the changes in the background color. (I also added a colorPrimary background to the toolbar here to make it more visible but the problem doesn't depend on the color, of course). The libraries are the latest as of today, 23.1.0.

Is there any workaround or we have to wait for it to be fixed in the library? Right now, it seems to be a showstopper for any app needing this functionality.

enterAlwaysCollapsed works but that gives a different functionality, it's not a workaround.

1 Answer 1

4

I solved this issue with a bit of patching to the AppBarLayout class source code. Apparently they didn't think people will use it like this. Or they did and I'm way off. anyways it works for me.

You need to make a small change to this method. look for SCROLL_FLAG_EXIT_UNTIL_COLLAPSED

 /**
 * Return the scroll range when scrolling down from a nested pre-scroll.
 */
private int getDownNestedPreScrollRange() {
    if (mDownPreScrollRange != INVALID_SCROLL_RANGE) {
        // If we already have a valid value, return it
        return mDownPreScrollRange;
    }

    int range = 0;
    for (int i = getChildCount() - 1; i >= 0; i--) {
        final View child = getChildAt(i);
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        final int childHeight = child.getMeasuredHeight();
        final int flags = lp.mScrollFlags;

        if ((flags & LayoutParams.FLAG_QUICK_RETURN) == LayoutParams.FLAG_QUICK_RETURN) {
            // First take the margin into account
            range += lp.topMargin + lp.bottomMargin;
            // The view has the quick return flag combination...
            if ((flags & LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED) != 0) {
                // If they're set to enter collapsed, use the minimum height
                range += ViewCompat.getMinimumHeight(child);
                // This is what is missing...
            } else if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) == LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) {
                range += childHeight - ViewCompat.getMinimumHeight(child);
            } else {
                // Else use the full height
                range += childHeight;
            }
        } else if (range > 0) {
            // If we've hit an non-quick return scrollable view, and we've already hit a
            // quick return view, return now
            break;
        }
    }
    return mDownPreScrollRange = range;
}

You may need to decrement the status bar height if you are using "android:fitsSystemWindows="true".

Hope it helps. There a some classes that you will need to copy from the design library to allow all imports & some methods that will turn public.

Cheers.

6
  • Clever. It probably works but I haven't yet managed to make all the dependent files work. :-) But could you post it in the Android issue queue? Chris Banes might welcome it and include it in the next release...
    – Gábor
    Commented Nov 2, 2015 at 21:37
  • Had to fix up the AppBarLayout code & the CollapsingToolbarLayout in order to make it work properly because of class dependencies. Too much work for such an issue. Hope they fix it soon.
    – TalMihr
    Commented Nov 3, 2015 at 7:02
  • I'm not sure they will unless you signal the problem and provide the solution there. :-)
    – Gábor
    Commented Nov 3, 2015 at 9:37
  • Forgive my ignorance but how do i do that?
    – TalMihr
    Commented Nov 3, 2015 at 9:38
  • I never did it myself, actually, but many a time you're sent to the issue queue like this: code.google.com/p/android/issues/detail?id=190226 . So, it seems that you simply submit a new issue (no need for separate registration, it's under Google all right)
    – Gábor
    Commented Nov 3, 2015 at 9:54