Cheesesquare: enterAlways produces wrong layout

笑着哭i 提交于 2019-12-12 11:14:32

问题


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:

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:


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.



来源:https://stackoverflow.com/questions/32539710/cheesesquare-enteralways-produces-wrong-layout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!