Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sticky Component inside scrollview

Tags:

react-native

I'm trying to build a a sticky component like this app

http://www.screencapture.ru/file/E88F08Fc

Deals, Products, Events tabs/segmentControl are actually start from bottom and as you scroll when you hit bottom of the header it stops and start stick while the content keep scrolled

this is my code

        <View style={styles.container}>
            <ScrollView 
                style={styles.container}
                scrollEventThrottle={16}
                onScroll={
                    Animated.event(
                        [{nativeEvent:{contentOffset: {y: this.state.scrollY}}}]
                    )
                }
            >
                {this._renderScrollViewContent()}
            </ScrollView>
            <View style={styles.stickyStuff}></View>
            <Animated.View
                style={[styles.header, {height: headerHeight}]}
            >
                <Animated.Image
                    source={require('../../assets/images/pvj.jpg')}
                    style={[styles.backgroundImage, {opacity: imageOpacity}]}
                />
                <Animated.View style={[styles.bar, {transform: [{translateY: titleTranslateY}, {translateX: titleTranslateX}]}]}>
                    <Text style={styles.title}>PARIS VAN JAVA</Text>
                </Animated.View>

            </Animated.View>
        </View>
like image 216
Bondan Herumurti Avatar asked Jul 26 '16 05:07

Bondan Herumurti


People also ask

Which is better FlatList or ScrollView?

As opposed to the ScrollView, the FlatList renders only those elements that are currently being displayed on the screen (default: 10 items). Thus, it does not have any impact on the performance of the application. So, it is preferable to use the FlatList Component to display a large list of data.

Can we use FlatList inside ScrollView react native?

"VirtualizedLists should never be nested inside plain ScrollViews with the same orientation" error in console for FlatList/SectionList with scrollEnabled={false}

What is contentContainerStyle?

contentContainerStyle: It is used to style the content of the ScrollView containers. contentInset: This property is used to inset the scroll view content by a specific amount. contentInsetAdjustmentBehavior: This property is used to identify how the safe area insets are used to modify the content area of the ScrollView ...

What is scrollEventThrottle?

scrollEventThrottle If you do not need precise scroll position tracking, set this value higher to limit the information being sent across the bridge. The default value is 0 , which results in the scroll event being sent only once each time the view is scrolled. Type. Default. number.


2 Answers

It is very simple with ScrollView component. There is already something called "stickyHeaderIndices" which takes the index of child to make sticky.In following code, content inside renderComponent2 stays sticky when you scroll.

<ScrollView
      stickyHeaderIndices={[1]}
      showsVerticalScrollIndicator={false}
 >
  {this.renderComponent1()}
  {this.renderComponent2()}
  {this.renderComponent3()}
 </ScrollView>

Refer: https://facebook.github.io/react-native/docs/scrollview.html#stickyheaderindices

like image 60
Muhammad Riyaz Avatar answered Oct 20 '22 20:10

Muhammad Riyaz


Thank you for answering my first question. I found it how to do it now. So basically what I do is I cheat on F8App code where they fallback from F8Scrolling native module if it is not available to this:

if (!NativeModules.F8Scrolling) {
  var distance = EMPTY_CELL_HEIGHT - this.state.stickyHeaderHeight;
  var translateY = 0; this.state.anim.interpolate({
    inputRange: [0, distance],
    outputRange: [distance, 0],
    extrapolateRight: 'clamp',
  });
  transform = [{translateY}];
}

which gives the idea of animating my sticky view so here is i ended up

const stickySegmentControlX = this.state.scrollY.interpolate({
    inputRange: [0, STICKY_SCROLL_DISTANCE],
    outputRange: [INIT_STICKY_HEADER, HEADER_MIN_HEIGHT],
    extrapolate: 'clamp'
})

...

    return(
    ....
     <Animated.View ref="stickyHeader" style={[styles.stickyStuff, {top: stickySegmentControlX}]}>
       <Text>Go Stick</Text>
     </Animated.View>
    ....
   );

so basically what I've done is animating the top position of an {position: 'absolute'}'s view while as the value of output range is between bottom position to the height of my header (so it'll stop right below my header) and the input range is between 0 and the difference of the top position and the header height. Eventually, the animation will feel natural as you scroll the scrollview.

There you go a sticky header custom view. Here is the result:

enter image description here

If you feel my answer is confusing, its better you heading to janic duplessis Medium post:
React Native ScrollView animated header

like image 20
Bondan Herumurti Avatar answered Oct 20 '22 21:10

Bondan Herumurti