Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlexboxLayoutManager does not handle Views without baselines well #388

Open
dlew opened this issue Dec 7, 2017 · 5 comments
Open

FlexboxLayoutManager does not handle Views without baselines well #388

dlew opened this issue Dec 7, 2017 · 5 comments
Labels

Comments

@dlew
Copy link

dlew commented Dec 7, 2017

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
Copy link
Author

dlew commented Dec 7, 2017

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.

@thagikura thagikura added the bug label Dec 8, 2017
@thagikura
Copy link
Contributor

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.

@dlew
Copy link
Author

dlew commented Dec 15, 2017

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.

@thagikura
Copy link
Contributor

Ok, thanks for the clarification.

@wangliangrc
Copy link

wangliangrc commented Jan 9, 2019

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

}

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants