Fix crash with js-based sticky headers
Summary: We're seeing ` inputRange must be monotonically increasing -1,0,0,-33,-32 ` which happens when we have zero height headers, wherever those come from...maybe rendering null? The math was also off and didn't handle variable height headers correctly, and it was confusing because it was `setNextHeaderY` with the header y _minus it's height_, which only works if the prev height was also the same height. Reviewed By: furdei Differential Revision: D4649404 fbshipit-source-id: c2c2d438fa0d0b979c2cbdfa5752eaf86c14768b
This commit is contained in:
parent
f6aad8b995
commit
94a333a2ea
|
@ -512,9 +512,7 @@ const ScrollView = React.createClass({
|
|||
];
|
||||
if (previousHeaderIndex != null) {
|
||||
const previousHeader = this._stickyHeaderRefs.get(previousHeaderIndex);
|
||||
previousHeader && previousHeader.setNextHeaderY(
|
||||
event.nativeEvent.layout.y - event.nativeEvent.layout.height,
|
||||
);
|
||||
previousHeader && previousHeader.setNextHeaderY(event.nativeEvent.layout.y);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ class ScrollViewStickyHeader extends React.Component {
|
|||
state = {
|
||||
measured: false,
|
||||
layoutY: 0,
|
||||
layoutHeight: 0,
|
||||
nextHeaderLayoutY: (null: ?number),
|
||||
};
|
||||
|
||||
|
@ -37,13 +38,14 @@ class ScrollViewStickyHeader extends React.Component {
|
|||
this.setState({
|
||||
measured: true,
|
||||
layoutY: event.nativeEvent.layout.y,
|
||||
layoutHeight: event.nativeEvent.layout.height,
|
||||
});
|
||||
|
||||
this.props.onLayout(event);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {measured, layoutY, nextHeaderLayoutY} = this.state;
|
||||
const {measured, layoutHeight, layoutY, nextHeaderLayoutY} = this.state;
|
||||
|
||||
let translateY;
|
||||
if (measured) {
|
||||
|
@ -51,17 +53,18 @@ class ScrollViewStickyHeader extends React.Component {
|
|||
// - Negative scroll: no translation
|
||||
// - From 0 to the y of the header: no translation. This will cause the header
|
||||
// to scroll normally until it reaches the top of the scroll view.
|
||||
// - From the header y to the next header y: translate equally to scroll.
|
||||
// This will cause the header to stay at the top of the scroll view.
|
||||
// - Past the the next header y: no more translation. This will cause the header
|
||||
// to continue scrolling up and make room for the next sticky header.
|
||||
// - From header y to when the next header y hits the bottom edge of the header: translate
|
||||
// equally to scroll. This will cause the header to stay at the top of the scroll view.
|
||||
// - Past the collision with the next header y: no more translation. This will cause the
|
||||
// header to continue scrolling up and make room for the next sticky header.
|
||||
// In the case that there is no next header just translate equally to
|
||||
// scroll indefinetly.
|
||||
const inputRange = [-1, 0, layoutY];
|
||||
const outputRange: Array<number> = [0, 0, 0];
|
||||
if (nextHeaderLayoutY != null) {
|
||||
inputRange.push(nextHeaderLayoutY, nextHeaderLayoutY + 1);
|
||||
outputRange.push(nextHeaderLayoutY - layoutY, nextHeaderLayoutY - layoutY);
|
||||
const collisionPoint = nextHeaderLayoutY - layoutHeight;
|
||||
inputRange.push(collisionPoint, collisionPoint + 1);
|
||||
outputRange.push(collisionPoint - layoutY, collisionPoint - layoutY);
|
||||
} else {
|
||||
inputRange.push(layoutY + 1);
|
||||
outputRange.push(1);
|
||||
|
|
Loading…
Reference in New Issue