facebook/litho

Elements outside the viewport are not drawn on entering

asier2 opened this issue · 2 comments

Version

0.41.1

Issues and Steps to Reproduce

  1. Instantiates an XML layout in a view, having it a scrollview. Said ScrollView must contain enough views to completely fill the viewport.

View view = View.inflate(this, R.layout.MyLayout, null);

MyLayout.xml

<LinearLayout>
    <ScrollView>
        <LinearLayout>
          VIEWS TAKING FULL WIEWPORT HEIGHT (TextView, ImageView...)
        </LinearLayout>
    </ScrollView>
</LinearLayout>
  1. Generate a LithoView and add it to the linear layout inside the scrollView.
LithoView lithoView = LithoView.create(this, Text.create(c).text("test").build());
ll.addView(lithoView); (ll being the internal layout of the scrollview)
  1. Set the view

setContentView(view);

Expected Behavior

The view is drawn on the screen.

Seen Behavior

The view is there, it takes its rightful place but it goes blank. Like a normal Android view with visibility View.Invisible. Using Flipper, the LithoView and its Text element are displayed, but the latter does not generate its TextDrawable unless I change a property in Flipper.

Hey @asier2, sorry about the trouble. Litho has 'incremental mount' on by default - this is a performance optimization which only mounts things within the viewport. The downside here is that when Litho is integrated into normal Android Views which can change the viewport (like a ScrollView), the change in viewport must be manually dispatched.

You can do this by extending ScrollView and overriding these methods:

  @Override
  protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);

    IncrementalMountUtils.incrementallyMountLithoViews(this);
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    IncrementalMountUtils.incrementallyMountLithoViews(this);
  }

Alternately, if you don't care about 'incremental mount', you can turn it off by setting .incrementalMount(false) when you create your ComponentTree.

ComponentTree ct = ComponentTree.create(c, Text.create(c).text("test").build())
    .incrementalMount(false)
    .build();
LithoView lithoView = new LithoView(this);
lithoView.setComponentTree(ct);

We're investing in trying to make viewport updates automatic but this isn't something ready to release yet.

It works as expected, thank you!