问题
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