flexbox-layout
flexbox-layout copied to clipboard
FlexboxLayoutManager does not handle Views without baselines well
Issues and steps to reproduce
- Create a
FlexboxLayoutManager
withalignItems =
AlignItems.BASELINE` - Use it on a
RecyclerView
that needs to wrap at least one line. - Repeatedly call
notifyDatasetChanged()
Expected behavior
Just calling notifyDatasetChanged()
should do nothing if none of the data changes.
Instead, the views keep moving around!
Version of the flexbox library
0.3.1
Link to code
The source of this issue is that View.getBaseline()
returns -1 by default. This causes the initial layout to have a marginTop of 1 instead of 0. That extra margin results in an extra row being laid out accidentally on the next pass.
Hi @dlew thanks for filing this issue. By any chance, did you attach the zip file same as the issue #389 ? I thought the project of the attached zip file tries to reproduce #389.
Yes, it's the same one - I forgot to mention that. You just need to modify the layout params in the project to reproduce either #388 or #389.
Ok, thanks for the clarification.
FlexboxLayoutManager and FlexboxHelper consist cache, I think this code is helpful: before by call
notifyDatasetChanged
just call:
` public void hack() { FlexboxLayoutManager flexboxLayoutManager = (FlexboxLayoutManager) mRecyclerView.getLayoutManager(); try { Field mFlexboxHelper = FlexboxLayoutManager.class.getDeclaredField("mFlexboxHelper"); mFlexboxHelper.setAccessible(true); Object flexboxHelper = mFlexboxHelper.get(flexboxLayoutManager);
Field mMeasureSpecCache = flexboxHelper.getClass().getDeclaredField("mMeasureSpecCache");
mMeasureSpecCache.setAccessible(true);
long[] measureSpecCache = (long[]) mMeasureSpecCache.get(flexboxHelper);
Field mMeasuredSizeCache = flexboxHelper.getClass().getDeclaredField("mMeasuredSizeCache");
mMeasuredSizeCache.setAccessible(true);
long[] measuredSizeCache = (long[]) mMeasureSpecCache.get(flexboxHelper);
mMeasureSpecCache.set(flexboxHelper, null);
mMeasureSpecCache.set(flexboxHelper, null);
Log.d("hack", "measureSpecCache " + measureSpecCache);
Log.d("hack", "measuredSizeCache " + measuredSizeCache);
/*Field mPendingScrollPosition = FlexboxLayoutManager.class.getDeclaredField("mPendingScrollPosition");
mPendingScrollPosition.setAccessible(true);
mPendingScrollPosition.set(flexboxLayoutManager, 0);
Field mDirtyPosition = FlexboxLayoutManager.class.getDeclaredField("mPendingScrollPosition");
mDirtyPosition.setAccessible(true);
mDirtyPosition.set(flexboxLayoutManager, 0);*/
Field mLastWidth = FlexboxLayoutManager.class.getDeclaredField("mLastWidth");
mLastWidth.setAccessible(true);
mLastWidth.set(flexboxLayoutManager, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
`