nicholas
nicholas

Reputation: 14563

Scroll to a row in a ReactNative ListView?

Any way of scrolling to a specific row in a React Native ListView?

I have the index of the row I want to scroll to. Following this thread I can get a reference to the row I want to scroll to. And I can use the list's scrollTo function to do the scrolling. But how do I tie that together; every method I try to find the offset of a row gives me NaNs or some other error.

Upvotes: 2

Views: 1211

Answers (1)

sodik
sodik

Reputation: 4683

maybe someone knows better solution, but I use following utility class for scrolling. Assuming you already have reference to the child, the basic idea is that you can measure child within the scrollview to determine its location and then you can compute the needed offset.

/**
scroll child within scrollView.

@param scrollView reference to scrollView
@param child - measureable child (see measureLayout in https://facebook.github.io/react-native/docs/nativemethodsmixin.html )
@param opt - options - (*default*)
{
  destination : *'top'*, 'bottom' : where to scroll - to the top or bottom of view
}
*/
export function scrollTo(scrollView, child, opt = {}) {
  const destination = opt.destination || TOP;

  const handle = React.findNodeHandle(scrollView);
  child.measureLayout(handle, (x,y, width, height) => {
    // kind of hack - not really documented feature
    scrollView.refs.ScrollView.measure((sx,sy, sw, sh, sPageX, sPageY) => {
      scrollView.refs.InnerScrollView.measure((isx,isy, isw, ish, isPageX, isPageY) => {
        console.log("scrollTo", x,y, width, height, sx,sy, sw, sh, sPageX, sPageY, isx,isy, isw, ish, isPageX, isPageY);
        const currentScrollPosition = sPageY - isPageY;
        if (currentScrollPosition <= y && y + height <= currentScrollPosition + sh) {
          // the child fits into scroll view -> noop
          console.log("fitting in");
        } else {
          if (destination === TOP) {
            if (y + sh > ish) {
              // we would scroll too much (there is not so much content after child to fill whole scroll view)
              scrollView.scrollTo({x:0, y: ish - sh});
            } else {
              scrollView.scrollTo({x:0, y});
            }
          } else {
            scrollView.scrollTo({x:0, y: y + height - sh});
          }
        }
      });
    });
  });

}

note - it just works with RN0.27+ (until they change internals of scrollview again :))

Upvotes: 2

Related Questions