Created
May 13, 2017 04:40
-
-
Save whoyawn/82fc6df0ffeceb68d538c351651a2748 to your computer and use it in GitHub Desktop.
Flatlist as view pager bug when trying to specify getItemLayout in props for use case, "scrolling to specific item on load"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sample React Native App | |
* https://github.com/facebook/react-native | |
* @flow | |
*/ | |
import React, { Component } from 'react'; | |
import { | |
AppRegistry, | |
} from 'react-native'; | |
import LogViewPager from './PageDetail' | |
export default class flatlisttest extends Component { | |
state = { | |
log: [{ key: 'page_one', date: 'tuesday', entries: [] }, | |
{ key: 'page_two', date: 'tuesday', entries: [] } | |
] | |
}; | |
render() { | |
return ( | |
<LogViewPager log={this.state.log} | |
onAddPage={() => this.setState({ | |
log: [...this.state.log, | |
{ key: Date.now(), date: 'tuesday', entries: [] } | |
] | |
}) | |
} | |
/> | |
); | |
} | |
} | |
AppRegistry.registerComponent('flatlisttest', () => flatlisttest); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by huyanh on 2017. 3. 22.. | |
*/ | |
import React, { Component } from 'react'; | |
import { Dimensions, FlatList, Platform, View, Text, StyleSheet, TouchableOpacity } from 'react-native'; | |
const LOREM_IPSUM = 'Lorem ipsum dolor sit amet, ius ad pertinax oportere accommodare, an vix \ | |
civibus corrumpit referrentur. Te nam case ludus inciderint, te mea facilisi adipiscing. Sea id \ | |
integre luptatum. In tota sale consequuntur nec. Erat ocurreret mei ei. Eu paulo sapientem \ | |
vulputate est, vel an accusam intellegam interesset. Nam eu stet pericula reprimique, ea vim illud \ | |
modus, putant invidunt reprehendunt ne qui.'; | |
function hashCode(str: string): number { | |
let hash = 15; | |
for (let ii = str.length - 1; ii >= 0; ii--) { | |
hash = ((hash << 5) - hash) + str.charCodeAt(ii); | |
} | |
return hash; | |
} | |
function genItemData(count: number, start: number = 0): Array<Item> { | |
const dataBlob = []; | |
for (let ii = start; ii < count + start; ii++) { | |
const itemHash = Math.abs(hashCode('Item ' + ii)); | |
dataBlob.push({ | |
title: 'Item ' + ii, | |
text: LOREM_IPSUM.substr(0, itemHash % 301 + 20), | |
key: String(ii), | |
pressed: false, | |
}); | |
} | |
return dataBlob; | |
} | |
export default class LogViewPager extends React.PureComponent { | |
state: State; | |
_listRef: FlatList<*>; | |
constructor(props: Props) { | |
super(props); | |
this.state = { | |
data: genItemData(2), | |
filterText: '', | |
height: 0, | |
width: 0, | |
selectedIndex: 0, | |
log: [{ key: 'page_one', date: 'tuesday', entries: [] }, | |
{ key: 'page_two', date: 'tuesday', entries: [] } | |
], | |
}; | |
(this: any).renderPage = this.renderPage.bind(this); | |
(this: any).adjustPageSize = this.adjustPageSize.bind(this); | |
} | |
componentWillMount() { | |
console.log('props'); | |
console.log(this.props.log) | |
console.log('state'); | |
console.log(this.state.log) | |
} | |
componentDidMount() { | |
this._listRef.scrollToEnd({ animated: false }); | |
} | |
render() { | |
const log = this.props.log.filter((item) => item); | |
return ( | |
<View style={{flex: 1}}> | |
<FlatList | |
ref={(flatList) => { | |
this._listRef = flatList; | |
}} | |
data={log} | |
onLayout={this.adjustPageSize} | |
renderItem={this.renderPage} | |
showsHorizontalScrollIndicator={false} | |
getItemLayout={(data, index) => { | |
const width = Dimensions.get('window').width; | |
// empty until scroll | |
return { length: width, offset: width * index, index }; | |
// to render, return this one | |
// return { length: 0, offset: width * index, index }; | |
}} | |
removeClippedSubviews={true} | |
horizontal | |
pagingEnabled | |
directionalLockEnabled | |
/> | |
<Text>{'props gets passed down properly: ' + this.props.log[0].date}</Text> | |
<TouchableOpacity style={{backgroundColor: 'red', paddingTop: 30}} | |
onPress={this.props.onAddPage}> | |
<Text>+</Text> | |
</TouchableOpacity> | |
</View> | |
); | |
} | |
adjustPageSize(e: any) { | |
this.setState({ | |
height: e.nativeEvent.layout.height, | |
width: e.nativeEvent.layout.width, | |
}); | |
} | |
renderPage({ item }): React.Element<any> { | |
return ( | |
<PageDetail | |
style={{ width: this.state.width }} | |
pageNum={item.key} | |
/> | |
); | |
} | |
} | |
class PageDetail extends React.PureComponent { | |
render() { | |
return ( | |
<View style={[styles.container, this.props.style]}> | |
<Text>{this.props.pageNum}</Text> | |
</View> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
backgroundColor: '#f56075', | |
...Platform.select({ | |
ios: { paddingTop: 30 }, | |
}), | |
}, | |
header: { | |
flex: 5, | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment