question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Sticky Headers with an External ScrollView

See original GitHub issue

I’ve been experimenting with the new externalScrollView prop trying to achieve a true sticky header experience. And this is what I came up with so far.

sticky-header-demo

My solution was replacing the normal ScrollView with an Animated.ScrollView and have its onScroll feed into an Animated value that I then use in the rowRenderer to stick some rows to the top.

This is my custom scrollview component.

class AnimatedScrollView extends React.Component {
  render() {
    return (
      <Animated.ScrollView
        ref={ref => (this._scrollView = ref)}
        scrollEventThrottle={1}
        {...this.props}
        onScroll={Animated.event(
          [{ nativeEvent: { contentOffset: { y:animatedScrollViewOffsetY } } }],
          {
            useNativeDriver: true,
            listener: this.props.onScroll
          }
        )}
      />
    );
  }
}

I then use the animatedScrollViewOffsetY Animated Value in the rowRenderer and I calculate when the views should start sticking to the top like that:

const stickyConfiguration = {
  startAt: 0,
  duration: -1 * HEADER_HEIGHT
};
_.forEach(this.state.dataProvider._data, (row, rowIndex) => {
  if (rowIndex < index) {
    stickyConfiguration.startAt += this.getRowHeight(row.viewType);
  } else {
    if (rowIndex > index && row.viewType === ViewTypes.DAY_HEADER) {
      return false;
    } else {
      stickyConfiguration.duration += this.getRowHeight(row.viewType);
    }
  }
});

I then pass the y:animatedScrollViewOffsetY to my component which positions itself with some transforms:

const translateY = {
  transform: [
    {
      translateY: this.props.animatedScrollViewOffsetY.interpolate({
        inputRange: [
          0,
          stickyConfiguration.startAt,
          stickyConfiguration.startAt + stickyConfiguration.duration
        ],
        outputRange: [0, 0, stickyConfiguration.duration],
        extrapolate: 'clamp'
      })
    }
  ]
};

One of the challenges I faced was with zIndex values. I fixed it for iOS by changing the code for ViewRenderer, but couldn’t fix it on Android. There’s also the problem with the onScroll event that has to run both the Animated.Event and do recyclerlistview’s logic as well. I couldn’t get around that myself.

I unfortunately can’t just fork recyclerlistview and implement my solution since it doesn’t work for Android yet, but that at least shows that the feature can be implemented. I’m thinking an additional property stickyViewTypes or something like that.

Please let me know if you need more clarification on how I made that demo work. Would love to have this added to recyclerlistview soon! 👍

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:14

github_iconTop GitHub Comments

2reactions
alpamys-qanybetcommented, Feb 10, 2018

@AbdallaMohamed, I found your workaround very nice, can you share your code?

0reactions
naqvitalhacommented, Jun 19, 2019

Sticky implementation is now part of RLV. Closing this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sticky Component inside scrollview - react native
It is very simple with ScrollView component. There is already something called "stickyHeaderIndices" which takes the index of child to make ...
Read more >
Using React Native ScrollView to create a sticky header
Create a custom sticky header with React Native ScrollView that shrinks, expands, and changes color on scroll to enhance your app's UX.
Read more >
SwiftUI Tutorial – Scaling Header - Exyte
A scroll view with a sticky header which shrinks as you scroll. Written with SwiftUI.
Read more >
react-native-sticky-header-footer-scroll-view - npm package
Sticky header and footer to any component and make it scrollable. For more information about how to use this package see README.
Read more >
ScrollView - React Native
A React Component that will be used to render sticky headers, should be used together with stickyHeaderIndices .
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found