propagate getScrollResponder, getScrollableNode

Summary:
so users can call `setNativeProps` and do more compositing.

**Test Plan:**

Added this to `onPress` of `SectionListExample` and `FlatListExample`:

    this._listRef.getNode().getScrollResponder().setNativeProps({scrollEnabled: false});

and saw scroll get disabled. Note the call to `getNode` because we are using the `Animated.createComponent` wrapper.

Reviewed By: achen1, bvaughn

Differential Revision: D4821711

fbshipit-source-id: 8d1f3dd7ccc646524f154721c5c7036620d57132
This commit is contained in:
Spencer Ahrens 2017-04-03 18:36:31 -07:00 committed by Facebook Github Bot
parent 128596b311
commit 87bdcbde6a
5 changed files with 63 additions and 6 deletions

View File

@ -13,7 +13,6 @@
const MetroListView = require('MetroListView'); // Used as a fallback legacy option
const React = require('React');
const ReactNative = require('ReactNative');
const View = require('View');
const VirtualizedList = require('VirtualizedList');
@ -297,11 +296,18 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
this._listRef.recordInteraction();
}
/**
* Provides a handle to the underlying scroll responder.
*/
getScrollResponder() {
if (this._listRef) {
return this._listRef.getScrollResponder();
}
}
getScrollableNode() {
if (this._listRef && this._listRef.getScrollableNode) {
if (this._listRef) {
return this._listRef.getScrollableNode();
} else {
return ReactNative.findNodeHandle(this._listRef);
}
}

View File

@ -67,6 +67,9 @@ class MetroListView extends React.Component {
this.props.horizontal ? {x: offset, animated} : {y: offset, animated}
);
}
getListRef() {
return this._listRef;
}
static defaultProps: DefaultProps = {
keyExtractor: (item, index) => item.key || index,
renderScrollComponent: (props: Props) => {

View File

@ -194,10 +194,40 @@ class SectionList<SectionT: SectionBase<any>>
props: Props<SectionT>;
static defaultProps: DefaultProps = defaultProps;
/**
* Tells the list an interaction has occured, which should trigger viewability calculations, e.g.
* if `waitForInteractions` is true and the user has not scrolled. This is typically called by
* taps on items or by navigation actions.
*/
recordInteraction() {
const listRef = this._wrapperListRef && this._wrapperListRef.getListRef();
listRef && listRef.recordInteraction();
}
/**
* Provides a handle to the underlying scroll responder.
*/
getScrollResponder() {
const listRef = this._wrapperListRef && this._wrapperListRef.getListRef();
if (listRef) {
return listRef.getScrollResponder();
}
}
getScrollableNode() {
const listRef = this._wrapperListRef && this._wrapperListRef.getListRef();
if (listRef) {
return listRef.getScrollableNode();
}
}
render() {
const List = this.props.legacyImplementation ? MetroListView : VirtualizedSectionList;
return <List {...this.props} />;
return <List {...this.props} ref={this._captureRef} />;
}
_wrapperListRef: MetroListView | VirtualizedSectionList<*>;
_captureRef = (ref) => { this._wrapperListRef = ref; };
}
module.exports = SectionList;

View File

@ -224,6 +224,17 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
this._updateViewableItems(this.props.data);
}
/**
* Provides a handle to the underlying scroll responder.
* Note that `this._scrollRef` might not be a `ScrollView`, so we
* need to check that it responds to `getScrollResponder` before calling it.
*/
getScrollResponder() {
if (this._scrollRef && this._scrollRef.getScrollResponder) {
return this._scrollRef.getScrollResponder();
}
}
getScrollableNode() {
if (this._scrollRef && this._scrollRef.getScrollableNode) {
return this._scrollRef.getScrollableNode();

View File

@ -119,6 +119,10 @@ class VirtualizedSectionList<SectionT: SectionBase>
data: [],
};
getListRef(): VirtualizedList {
return this._listRef;
}
_keyExtractor = (item: Item, index: number) => {
const info = this._subExtractor(index);
return (info && info.key) || String(index);
@ -257,8 +261,11 @@ class VirtualizedSectionList<SectionT: SectionBase>
}
render() {
return <VirtualizedList {...this.state.childProps} />;
return <VirtualizedList {...this.state.childProps} ref={this._captureRef} />;
}
_listRef: VirtualizedList;
_captureRef = (ref) => { this._listRef = ref; };
}
function getItem(sections: ?Array<Item>, index: number): ?Item {