Reputation: 2098
I want to detect which section of the react-native sectionlist is in the viewport.
Is there any solution?
Upvotes: 8
Views: 6544
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
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.
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