enact icon indicating copy to clipboard operation
enact copied to clipboard

PoC to various sizes of items in VirtualList

Open 0x64 opened this issue 6 years ago • 1 comments

Checklist

  • [x] I have read and understand the contribution guide
  • [ ] A CHANGELOG entry is included
  • [ ] At least one test case is included for this feature or bug fix
  • [ ] Documentation was added or is not needed
  • [ ] This is an API breaking change

Issue Resolved / Feature Added

This is a PoC for a virtualized list feature to support items which do not have the same size but various sizes, especially, regarding arbitrary scrollTo requests from apps in case of that a list cannot know item sizes before render since an item's content is dynamically decided.

So, I assumed the requirements below;

  • A list should render a visual part of all items. (Virtualized)
  • An app does not know the size of an item. A list should measure it.
  • An app can move the scroll position without animation to any scrollable position.
  • When a user rotates a wheel on a mouse, a list should be able to any position without stuttering.
  • A list should be able to scroll by 5-way key input.

Maybe one of the most complex scenario for this feature is to scroll upward after scroll(jump) to the last position within a list.

Resolution

Since the size of an item is unknown to a list, the list must measure sizes after render. Also to adjust item positions without stuttering, Items' positions and/or the scroll position should be adjusted gradually.

So, the basic concept is;

  • Cache already measured size and position info. The position info can be updated by adjustments.
  • Measure rendered items after mounting and updating.
    • To support gentle scrolling, find nearby items which are already rendered earlier.
    • If some items visible was visible in the previous update, set up positions for other newly rendered items based on already visible items.
    • If no item was visible in the previous frame, apply cached positions or estimate positions.
    • So, there is no adjustment in this step. There is only positioning.
    • Note that if a list scrolls only downward, we've done everything in this step since we don't have any gap to adjust after positioning.
  • Adjust item positions during scroll
    • Get diff between estimated positions based on the minimum size of items and measured/calculated positions of cached info.
    • Update item positions and update cached position info with a capped gap for gentle scrolling. (If there is no cap, a list could be jump during scroll by a wheel)
    • Note that this adjustment is required for upward scrolling.
  • Adjust item positions and the scroll position when scroll stops.

Additional Considerations

Following cases are NOT considered to get a result quickly.

  • Horizontal lists: it's logically equivalent to a vertical list.
  • Grid lists: basically implemented also regarding grid lists, but not fully tested.
  • Did not fully tuned to simplify logic
  • Paging scroll by keys: only considered arrow keys on testing

Known Issues

During scroll by 5-way arrow keys, adjustment code moves items, so the focused item is not sticking to the edge sometimes. If we change internal components to share the intention for each scrolling (e.g 'scrolling to the index', 'scrolling by wheeling', 'scrolling by data size changed', etc), it seems to be possible to support this. But in native lists, a list actually handles item positioning with a lazy approach in 'scroll' event handler and a list does not know which input leads scrolling exactly. And we need bigger structural changes to share the intention internally.

Links

PLAT-71282

0x64 avatar Feb 21 '19 05:02 0x64

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Oct 28 '21 08:10 CLAassistant