flexbox-layout icon indicating copy to clipboard operation
flexbox-layout copied to clipboard

FlexboxLayoutManager does not handle Views without baselines well

Open dlew opened this issue 6 years ago • 5 comments

Issues and steps to reproduce

  1. Create a FlexboxLayoutManager with alignItems = AlignItems.BASELINE`
  2. Use it on a RecyclerView that needs to wrap at least one line.
  3. Repeatedly call notifyDatasetChanged()

Expected behavior

Just calling notifyDatasetChanged() should do nothing if none of the data changes.

Instead, the views keep moving around!

screencast-genymotion-2017-12-07_11 14 42 395

Version of the flexbox library

0.3.1

Link to code

FlexBug.zip

dlew avatar Dec 07 '17 17:12 dlew

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.

dlew avatar Dec 07 '17 17:12 dlew

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.

thagikura avatar Dec 15 '17 03:12 thagikura

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.

dlew avatar Dec 15 '17 04:12 dlew

Ok, thanks for the clarification.

thagikura avatar Dec 15 '17 05:12 thagikura

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();
    }

}

`

wangliangrc avatar Jan 09 '19 09:01 wangliangrc