Hamid
Hamid

Reputation: 2098

Getting the current section that is in the viewport in React-Native sectionlist

I want to detect which section of the react-native sectionlist is in the viewport. enter image description here

Is there any solution?

Upvotes: 8

Views: 6544

Answers (2)

Haider Ali
Haider Ali

Reputation: 1285

This is what you can do

  render () {
    return (
      <SectionList
        onViewableItemsChanged={this.onCheckViewableItems}
        viewabilityConfig={{
          itemVisiblePercentThreshold: 50 //means if 50% of the item is visible
        }}
      />
    )
  }

onCheckViewableItems = ({ viewableItems, changed }) => {
        console.log("Visible items :", viewableItems)
      }

Upvotes: 9

eemmrrkk
eemmrrkk

Reputation: 1710

Let's assume that the section provide its sections from data prop of the state.

state = { data: [...], contentSizeData: [], currentSection: 0 }

And assume that your SectionList is like that.

<SectionList
  onScroll={event => {    
     for (var _i = 0; _i < this.state.contentSizeData.length; _i++) {
      if (event.nativeEvent.contentOffset.y < this.state.contentSizeData[_i]) {
           this.setState({ currentSection: _i });
           break;
          }
       }
    }}
    renderItem={({ item, index, section }) => {
      <ItemComponent />
    }}
    renderSectionHeader={({ section }) => {
      <HeaderComponent />
    }}
    sections={this.state.data}
/>

You must calculate the content size of the total renderedItems with including renderedHeaders and in onScroll method regarding to contentOffset of SectionList we can check out that which section it is.

Suppose that you have 2 sections which has 3 items with headers. Each renderedItem has height of 100 and headers has height of 20 which looks like to example of bottom.

enter image description here

Then you have to create a logic with a loop that calculate of the content sizes of each section (calculate each section's height with including its header)

    var _sizeArr = []
    for(var _iter = 0; _iter < this.state.data.length; _iter++){
      let cellsHeight = this.state.data[_iter].length * 100;
      let headerHeight = 20;
      var totalHeight = cellsHeight + headerHeight;
      if(_iter != 0){
         _sizeArr.push(totalHeight + _sizeArr[_iter-1]); 
      }else{
         _sizeArr.push(totalHeight); 
      }
     }
   this.setState({ contentSizeData: _sizeArr })

Let's look at section's height

For first one 20 (header component) + 3 * 100 (item component) => 320

And second one 20 (header component) + 3 * 100 (item component) => 320

In this.state.contentSizeData array includes 2 height such as [320, 640]. Second one contains own section's height and section height which before itself. This means we use SectionList's onScroll method with looking at contentOffset.y and we can check that if SectionList's y position is between [0 - 320] so its in Section 0 and if not loop iterate and check if its between [320 - 640], if so its in Section 1.

onScroll = {event => {
    for (var _i = 0; _i < this.state.contentSizeData.length; _i++) {
       if (event.nativeEvent.contentOffset.y < this.state.contentSizeData[_i]) {
           this.setState({ currentSection: _i });
           break;
        }
    }
}}

When you scroll in SectionList, it triggered onScroll method and you can see the currentSection in the state.

Upvotes: 1

Related Questions