Support sticky headers for inverted Lists

Summary:
Sticky headers for inverted lists should still stick at the top of the list instead of the bottom.

Tested by adding the inverted prop to the SectionList example in RNTester.

It does add a prop to ScrollView but it's very specific to the inverted list implementation, not sure if it should be documented.

[GENERAL][ENHANCEMENT][LISTS] -  Support sticky headers for inverted Lists
Closes https://github.com/facebook/react-native/pull/17762

Differential Revision: D6830784

Pulled By: sahrens

fbshipit-source-id: 6841fdd46e04b30547659d85ff54c3a21c61a8a2
This commit is contained in:
Janic Duplessis
2018-01-29 11:43:50 -08:00
committed by Facebook Github Bot
parent 429fcc8cab
commit ecaca80d42
6 changed files with 124 additions and 36 deletions

View File

@@ -190,6 +190,11 @@ const ScrollView = createReactClass({
'black',
'white',
]),
/**
* If sticky headers should stick at the bottom instead of the top of the
* ScrollView. This is usually used with inverted ScrollViews.
*/
invertStickyHeaders: PropTypes.bool,
/**
* When true, the ScrollView will try to lock to only vertical or horizontal
* scrolling while dragging. The default value is false.
@@ -499,7 +504,10 @@ const ScrollView = createReactClass({
_stickyHeaderRefs: (new Map(): Map<number, ScrollViewStickyHeader>),
_headerLayoutYs: (new Map(): Map<string, number>),
getInitialState: function() {
return this.scrollResponderMixinGetInitialState();
return {
...this.scrollResponderMixinGetInitialState(),
layoutHeight: null,
};
},
componentWillMount: function() {
@@ -676,6 +684,15 @@ const ScrollView = createReactClass({
this.scrollResponderHandleScroll(e);
},
_handleLayout: function(e: Object) {
if (this.props.invertStickyHeaders) {
this.setState({ layoutHeight: e.nativeEvent.layout.height });
}
if (this.props.onLayout) {
this.props.onLayout(e);
}
},
_handleContentOnLayout: function(e: Object) {
const {width, height} = e.nativeEvent.layout;
this.props.onContentSizeChange && this.props.onContentSizeChange(width, height);
@@ -761,7 +778,9 @@ const ScrollView = createReactClass({
this._headerLayoutYs.get(this._getKeyForIndex(nextIndex, childArray))
}
onLayout={(event) => this._onStickyHeaderLayout(index, event, key)}
scrollAnimatedValue={this._scrollAnimatedValue}>
scrollAnimatedValue={this._scrollAnimatedValue}
inverted={this.props.invertStickyHeaders}
scrollViewHeight={this.state.layoutHeight}>
{child}
</ScrollViewStickyHeader>
);
@@ -808,6 +827,7 @@ const ScrollView = createReactClass({
// Override the onContentSizeChange from props, since this event can
// bubble up from TextInputs
onContentSizeChange: null,
onLayout: this._handleLayout,
onMomentumScrollBegin: this.scrollResponderHandleMomentumScrollBegin,
onMomentumScrollEnd: this.scrollResponderHandleMomentumScrollEnd,
onResponderGrant: this.scrollResponderHandleResponderGrant,