robert-luoqing / flutter_list_view

MIT License
47 stars 17 forks source link

Sticky header and reverse list #6

Closed anormal81 closed 8 months ago

anormal81 commented 2 years ago

Following your chat example in issue #5, I got the list up and running. Now I activated the sticky header.

onItemSticky: (index) {
          if (index >= messageIds.length) {
            return false;
          }
          return messageIds[index].startsWith("date-separator-");
}

Problem The correct items are displayed sticky, but due to a reversed list, the sticky element gets visible on top when leaving the bottom edge. It also breaks the keepPosition mechanism.

Expected For reverse lists, the sticky header must perform as in non-reverse lists as shown in your example:

robert-bitguild commented 2 years ago

Current sticky header is not work on reverse mode. I will schedule time to work it late.

anormal81 commented 2 years ago

According to the changelog, sticky header should work with version 1.1.11

There are two problems when using onItemSticky in a reverse list:

  1. I sometimes can not scroll to the top of the list. When the sticky header becomes visible, the list scrolls some pixels away
  2. The sticky header seems to be positioned at the bottom of the list. This is really not expected and should look like in a non-reversed list. A header should always be at the top of the viewport.

stickyoff stickyon

robert-bitguild commented 2 years ago

@anormal81 I got what you said it should support sticky tailer item in reverse model. I will schedule to support it soon.

robert-bitguild commented 2 years ago

@anormal81 Sticky in reverse mode is working now. You can add stickyAtTailer: true, make sure the sticky is from bottom to top in reverse mode.

FlutterListView(
    reverse: true,
    delegate: FlutterListViewDelegate(
      (BuildContext context, int index) {
        var data = _countries[index];
        if (data is AlphabetHeader) {
          return _renderHeader(data.alphabet);
        } else {
          return _renderItem(data as CountryModel);
        }
      },
      childCount: _countries.length,
      onItemSticky: (index) => _countries[index] is AlphabetHeader,
      stickyAtTailer: true,
    ),
    controller: controller)
anormal81 commented 2 years ago

@robert-bitguild Thank you, works great :-)

One little problem: When an item is large (I mean very, very, very large), the sticky header won't be shown when scrolling over this item. That's no blocker for me ;-)

Does the sticky header feature check each item of the data to be sticky or only the already rendered items?

robert-bitguild commented 2 years ago

@anormal81 I will check the first issue later.

But I didn't understand the second problem? What mean the rendered items. For example, suppose the widget have 10000 items, If the widget jump to 1000th item with initIndex, only 1000th-1010th items actually rendered. In this scenario, the rendered items should be 1-1010th or 1000th-1010th?

anormal81 commented 2 years ago

The second part was just a question, not a problem ;-)

I'll try to describe it again in more detail: If the widget has 10000 items and jumped to item 10000, then only some are rendered (painted). If the last item for the sticky header is now at position 5, is it also displayed?