Quentin Lerebours
Quentin Lerebours

Reputation: 766

How to add an offset for ReactNative SectionList items viewability

I have a ReactNative application with a SectionList. There's an absolute positioned header over the list which contains the names of the sections. When scrolling this list, I need to update which section is currently scrolled.

Here is my code:

const handleChangeSelectedIndexWithScroll = ({ viewableItems }) => {
  if (!viewableItems || viewableItems.length === 0) {
    return;
  }

  // Get which section is visible on the screen
  const visibleSectionsId = viewableItems.map(
    (viewableItem) => viewableItem.section.index
  );

  // Say that the currently scrolled section is the first one that has any visible item.
  // By doing this, if the first section has any single visible item, it will be the one selected
  setCurrentSectionScrolled(Math.min(...visibleSectionsId));
};

<SectionList
        ref={recipeDetailsRef}
        sections={data}
        onViewableItemsChanged={handleChangeSelectedIndexWithScroll}
/>

The problem: With the absolute header, the scroll isn't well reflected because RN considers that the section's items are visible on screen when in fact, they can be hidden behind the header.

Screenshot enter image description here On this image, you can see that the current selected section is "Ingredients" when in fact, we're already on "Materiels", because behind the absolute header, there's still an Ingredient visible to RN

Considered solutions:

This is why I was wondering if there was a single solution to say to RN: "Please consider that there is an offset of 50px for this list", so that they don't consider visible items if they are in this offset

Thanks

Upvotes: 1

Views: 633

Answers (2)

If you encounter this problem, try setting:

transform: [{
  translateY: HEADER_HEIGHT
}]

In contentStyle and to compensate for this offset set paddingBottom: HEADER_HEIGHT in the same contentStyle. This worked for me on an example chat application with inverted flat list and absolute blur header where I used instead of paddingBottom paddingTop and negative transform

Upvotes: 0

hong developer
hong developer

Reputation: 13926

If you want to change the active item, you can use the following method.

const handleChangeSelectedIndexWithScroll = ({ changed , viewableItems }) => {
  if (!viewableItems || viewableItems.length === 0) {
    return;
  }
  
  const sectionIndex = viewableItems.length - changed.length

  setCurrentSectionScrolled(sectionIndex);
};

Upvotes: 0

Related Questions