native animated scroll event support
Reviewed By: yungsters Differential Revision: D4648383 fbshipit-source-id: fdb8e2deaa06b2d2f9002cee2c0b827dbd7a5570
This commit is contained in:
parent
28ed5eddf2
commit
5177a55314
|
@ -26,6 +26,7 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const ReactNative = require('react-native');
|
const ReactNative = require('react-native');
|
||||||
const {
|
const {
|
||||||
|
Animated,
|
||||||
FlatList,
|
FlatList,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
|
@ -47,6 +48,8 @@ const {
|
||||||
renderSmallSwitchOption,
|
renderSmallSwitchOption,
|
||||||
} = require('./ListExampleShared');
|
} = require('./ListExampleShared');
|
||||||
|
|
||||||
|
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
|
||||||
|
|
||||||
const VIEWABILITY_CONFIG = {
|
const VIEWABILITY_CONFIG = {
|
||||||
minimumViewTime: 3000,
|
minimumViewTime: 3000,
|
||||||
viewAreaCoveragePercentThreshold: 100,
|
viewAreaCoveragePercentThreshold: 100,
|
||||||
|
@ -66,15 +69,29 @@ class FlatListExample extends React.PureComponent {
|
||||||
logViewable: false,
|
logViewable: false,
|
||||||
virtualized: true,
|
virtualized: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
_onChangeFilterText = (filterText) => {
|
_onChangeFilterText = (filterText) => {
|
||||||
this.setState({filterText});
|
this.setState({filterText});
|
||||||
};
|
};
|
||||||
|
|
||||||
_onChangeScrollToIndex = (text) => {
|
_onChangeScrollToIndex = (text) => {
|
||||||
this._listRef.scrollToIndex({viewPosition: 0.5, index: Number(text)});
|
this._listRef.getNode().scrollToIndex({viewPosition: 0.5, index: Number(text)});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_scrollPos = new Animated.Value(0);
|
||||||
|
_scrollSinkX = Animated.event(
|
||||||
|
[{nativeEvent: { contentOffset: { x: this._scrollPos } }}],
|
||||||
|
{useNativeDriver: true},
|
||||||
|
);
|
||||||
|
_scrollSinkY = Animated.event(
|
||||||
|
[{nativeEvent: { contentOffset: { y: this._scrollPos } }}],
|
||||||
|
{useNativeDriver: true},
|
||||||
|
);
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
this._listRef.recordInteraction(); // e.g. flipping logViewable switch
|
this._listRef.getNode().recordInteraction(); // e.g. flipping logViewable switch
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const filterRegex = new RegExp(String(this.state.filterText), 'i');
|
const filterRegex = new RegExp(String(this.state.filterText), 'i');
|
||||||
const filter = (item) => (
|
const filter = (item) => (
|
||||||
|
@ -95,7 +112,6 @@ class FlatListExample extends React.PureComponent {
|
||||||
<PlainInput
|
<PlainInput
|
||||||
onChangeText={this._onChangeScrollToIndex}
|
onChangeText={this._onChangeScrollToIndex}
|
||||||
placeholder="scrollToIndex..."
|
placeholder="scrollToIndex..."
|
||||||
style={styles.searchTextInput}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.options}>
|
<View style={styles.options}>
|
||||||
|
@ -104,10 +120,19 @@ class FlatListExample extends React.PureComponent {
|
||||||
{renderSmallSwitchOption(this, 'fixedHeight')}
|
{renderSmallSwitchOption(this, 'fixedHeight')}
|
||||||
{renderSmallSwitchOption(this, 'logViewable')}
|
{renderSmallSwitchOption(this, 'logViewable')}
|
||||||
{renderSmallSwitchOption(this, 'debug')}
|
{renderSmallSwitchOption(this, 'debug')}
|
||||||
|
<Animated.View style={[styles.spindicator, {
|
||||||
|
transform: [
|
||||||
|
{rotate: this._scrollPos.interpolate({
|
||||||
|
inputRange: [0, 5000],
|
||||||
|
outputRange: ['0deg', '360deg'],
|
||||||
|
extrapolate: 'extend',
|
||||||
|
})}
|
||||||
|
]
|
||||||
|
}]} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<SeparatorComponent />
|
<SeparatorComponent />
|
||||||
<FlatList
|
<AnimatedFlatList
|
||||||
HeaderComponent={HeaderComponent}
|
HeaderComponent={HeaderComponent}
|
||||||
FooterComponent={FooterComponent}
|
FooterComponent={FooterComponent}
|
||||||
SeparatorComponent={SeparatorComponent}
|
SeparatorComponent={SeparatorComponent}
|
||||||
|
@ -125,6 +150,7 @@ class FlatListExample extends React.PureComponent {
|
||||||
legacyImplementation={false}
|
legacyImplementation={false}
|
||||||
numColumns={1}
|
numColumns={1}
|
||||||
onRefresh={this._onRefresh}
|
onRefresh={this._onRefresh}
|
||||||
|
onScroll={this.state.horizontal ? this._scrollSinkX : this._scrollSinkY}
|
||||||
onViewableItemsChanged={this._onViewableItemsChanged}
|
onViewableItemsChanged={this._onViewableItemsChanged}
|
||||||
ref={this._captureRef}
|
ref={this._captureRef}
|
||||||
refreshing={false}
|
refreshing={false}
|
||||||
|
@ -180,7 +206,7 @@ class FlatListExample extends React.PureComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_pressItem = (key: number) => {
|
_pressItem = (key: number) => {
|
||||||
this._listRef.recordInteraction();
|
this._listRef.getNode().recordInteraction();
|
||||||
pressItem(this, key);
|
pressItem(this, key);
|
||||||
};
|
};
|
||||||
_listRef: FlatList<*>;
|
_listRef: FlatList<*>;
|
||||||
|
@ -196,6 +222,12 @@ const styles = StyleSheet.create({
|
||||||
searchRow: {
|
searchRow: {
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
},
|
},
|
||||||
|
spindicator: {
|
||||||
|
marginLeft: 'auto',
|
||||||
|
width: 2,
|
||||||
|
height: 16,
|
||||||
|
backgroundColor: 'darkgray',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = FlatListExample;
|
module.exports = FlatListExample;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
const MetroListView = require('MetroListView'); // Used as a fallback legacy option
|
const MetroListView = require('MetroListView'); // Used as a fallback legacy option
|
||||||
const React = require('React');
|
const React = require('React');
|
||||||
|
const ReactNative = require('ReactNative');
|
||||||
const View = require('View');
|
const View = require('View');
|
||||||
const VirtualizedList = require('VirtualizedList');
|
const VirtualizedList = require('VirtualizedList');
|
||||||
|
|
||||||
|
@ -235,6 +236,14 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
|
||||||
this._listRef.recordInteraction();
|
this._listRef.recordInteraction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getScrollableNode() {
|
||||||
|
if (this._listRef && this._listRef.getScrollableNode) {
|
||||||
|
return this._listRef.getScrollableNode();
|
||||||
|
} else {
|
||||||
|
return ReactNative.findNodeHandle(this._listRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this._checkProps(this.props);
|
this._checkProps(this.props);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
const Batchinator = require('Batchinator');
|
const Batchinator = require('Batchinator');
|
||||||
const React = require('React');
|
const React = require('React');
|
||||||
|
const ReactNative = require('ReactNative');
|
||||||
const RefreshControl = require('RefreshControl');
|
const RefreshControl = require('RefreshControl');
|
||||||
const ScrollView = require('ScrollView');
|
const ScrollView = require('ScrollView');
|
||||||
const View = require('View');
|
const View = require('View');
|
||||||
|
@ -237,6 +238,14 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
|
||||||
this._updateViewableItems(this.props.data);
|
this._updateViewableItems(this.props.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getScrollableNode() {
|
||||||
|
if (this._scrollRef && this._scrollRef.getScrollableNode) {
|
||||||
|
return this._scrollRef.getScrollableNode();
|
||||||
|
} else {
|
||||||
|
return ReactNative.findNodeHandle(this._scrollRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
disableVirtualization: false,
|
disableVirtualization: false,
|
||||||
getItem: (data: any, index: number) => data[index],
|
getItem: (data: any, index: number) => data[index],
|
||||||
|
@ -293,7 +302,8 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
|
||||||
super(props);
|
super(props);
|
||||||
invariant(
|
invariant(
|
||||||
!props.onScroll || !props.onScroll.__isNative,
|
!props.onScroll || !props.onScroll.__isNative,
|
||||||
'VirtualizedList does not support AnimatedEvent with onScroll and useNativeDriver',
|
'Components based on VirtualizedList must be wrapped with Animated.createAnimatedComponent ' +
|
||||||
|
'to support native onScroll events with useNativeDriver',
|
||||||
);
|
);
|
||||||
this._updateCellsToRenderBatcher = new Batchinator(
|
this._updateCellsToRenderBatcher = new Batchinator(
|
||||||
this._updateCellsToRender,
|
this._updateCellsToRender,
|
||||||
|
|
Loading…
Reference in New Issue