293 lines
7.1 KiB
JavaScript
293 lines
7.1 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
* @flow
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var React = require('react');
|
|
var ReactNative = require('react-native');
|
|
var {
|
|
Image,
|
|
LayoutAnimation,
|
|
ListView,
|
|
StyleSheet,
|
|
Text,
|
|
TouchableOpacity,
|
|
View,
|
|
} = ReactNative;
|
|
|
|
var NativeModules = require('NativeModules');
|
|
var {UIManager} = NativeModules;
|
|
|
|
var THUMB_URLS = [
|
|
require('./Thumbnails/like.png'),
|
|
require('./Thumbnails/dislike.png'),
|
|
require('./Thumbnails/call.png'),
|
|
require('./Thumbnails/fist.png'),
|
|
require('./Thumbnails/bandaged.png'),
|
|
require('./Thumbnails/flowers.png'),
|
|
require('./Thumbnails/heart.png'),
|
|
require('./Thumbnails/liking.png'),
|
|
require('./Thumbnails/party.png'),
|
|
require('./Thumbnails/poke.png'),
|
|
require('./Thumbnails/superlike.png'),
|
|
require('./Thumbnails/victory.png'),
|
|
];
|
|
var NUM_SECTIONS = 100;
|
|
var NUM_ROWS_PER_SECTION = 10;
|
|
|
|
class Thumb extends React.Component<{}, $FlowFixMeState> {
|
|
UNSAFE_componentWillMount() {
|
|
UIManager.setLayoutAnimationEnabledExperimental &&
|
|
UIManager.setLayoutAnimationEnabledExperimental(true);
|
|
}
|
|
|
|
_getThumbIdx = () => {
|
|
return Math.floor(Math.random() * THUMB_URLS.length);
|
|
};
|
|
|
|
_onPressThumb = () => {
|
|
var config =
|
|
layoutAnimationConfigs[
|
|
this.state.thumbIndex % layoutAnimationConfigs.length
|
|
];
|
|
LayoutAnimation.configureNext(config);
|
|
this.setState({
|
|
thumbIndex: this._getThumbIdx(),
|
|
dir: this.state.dir === 'row' ? 'column' : 'row',
|
|
});
|
|
};
|
|
|
|
state = {thumbIndex: this._getThumbIdx(), dir: 'row'};
|
|
|
|
render() {
|
|
return (
|
|
<TouchableOpacity
|
|
onPress={this._onPressThumb}
|
|
style={[styles.buttonContents, {flexDirection: this.state.dir}]}>
|
|
<Image style={styles.img} source={THUMB_URLS[this.state.thumbIndex]} />
|
|
<Image style={styles.img} source={THUMB_URLS[this.state.thumbIndex]} />
|
|
<Image style={styles.img} source={THUMB_URLS[this.state.thumbIndex]} />
|
|
{this.state.dir === 'column' ? (
|
|
<Text>
|
|
Oooo, look at this new text! So awesome it may just be crazy. Let me
|
|
keep typing here so it wraps at least one line.
|
|
</Text>
|
|
) : (
|
|
<Text />
|
|
)}
|
|
</TouchableOpacity>
|
|
);
|
|
}
|
|
}
|
|
|
|
class ListViewPagingExample extends React.Component<$FlowFixMeProps, *> {
|
|
static title = '<ListView> - Paging';
|
|
static description = 'Floating headers & layout animations.';
|
|
|
|
// $FlowFixMe found when converting React.createClass to ES6
|
|
constructor(props) {
|
|
super(props);
|
|
var getSectionData = (dataBlob, sectionID) => {
|
|
return dataBlob[sectionID];
|
|
};
|
|
var getRowData = (dataBlob, sectionID, rowID) => {
|
|
return dataBlob[rowID];
|
|
};
|
|
|
|
var dataSource = new ListView.DataSource({
|
|
getRowData: getRowData,
|
|
getSectionHeaderData: getSectionData,
|
|
rowHasChanged: (row1, row2) => row1 !== row2,
|
|
sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
|
|
});
|
|
|
|
var dataBlob = {};
|
|
var sectionIDs = [];
|
|
var rowIDs = [];
|
|
for (var ii = 0; ii < NUM_SECTIONS; ii++) {
|
|
var sectionName = 'Section ' + ii;
|
|
sectionIDs.push(sectionName);
|
|
dataBlob[sectionName] = sectionName;
|
|
rowIDs[ii] = [];
|
|
|
|
for (var jj = 0; jj < NUM_ROWS_PER_SECTION; jj++) {
|
|
var rowName = 'S' + ii + ', R' + jj;
|
|
rowIDs[ii].push(rowName);
|
|
dataBlob[rowName] = rowName;
|
|
}
|
|
}
|
|
|
|
this.state = {
|
|
dataSource: dataSource.cloneWithRowsAndSections(
|
|
dataBlob,
|
|
sectionIDs,
|
|
rowIDs,
|
|
),
|
|
headerPressCount: 0,
|
|
};
|
|
}
|
|
|
|
renderRow = (
|
|
rowData: string,
|
|
sectionID: string,
|
|
rowID: string,
|
|
): React.Element<any> => {
|
|
return <Thumb text={rowData} />;
|
|
};
|
|
|
|
renderSectionHeader = (sectionData: string, sectionID: string) => {
|
|
return (
|
|
<View style={styles.section}>
|
|
<Text style={styles.text}>{sectionData}</Text>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
renderHeader = () => {
|
|
var headerLikeText =
|
|
this.state.headerPressCount % 2 ? (
|
|
<View>
|
|
<Text style={styles.text}>1 Like</Text>
|
|
</View>
|
|
) : null;
|
|
return (
|
|
<TouchableOpacity onPress={this._onPressHeader} style={styles.header}>
|
|
{headerLikeText}
|
|
<View>
|
|
<Text style={styles.text}>Table Header (click me)</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|
|
|
|
renderFooter = () => {
|
|
return (
|
|
<View style={styles.header}>
|
|
<Text onPress={() => console.log('Footer!')} style={styles.text}>
|
|
Table Footer
|
|
</Text>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<ListView
|
|
style={styles.listview}
|
|
dataSource={this.state.dataSource}
|
|
onChangeVisibleRows={(visibleRows, changedRows) =>
|
|
console.log({visibleRows, changedRows})
|
|
}
|
|
renderHeader={this.renderHeader}
|
|
renderFooter={this.renderFooter}
|
|
renderSectionHeader={this.renderSectionHeader}
|
|
renderRow={this.renderRow}
|
|
initialListSize={10}
|
|
pageSize={4}
|
|
scrollRenderAheadDistance={500}
|
|
stickySectionHeadersEnabled
|
|
/>
|
|
);
|
|
}
|
|
|
|
_onPressHeader = () => {
|
|
var config =
|
|
layoutAnimationConfigs[
|
|
Math.floor(this.state.headerPressCount / 2) %
|
|
layoutAnimationConfigs.length
|
|
];
|
|
LayoutAnimation.configureNext(config);
|
|
this.setState({headerPressCount: this.state.headerPressCount + 1});
|
|
};
|
|
}
|
|
|
|
var styles = StyleSheet.create({
|
|
listview: {
|
|
backgroundColor: '#B0C4DE',
|
|
},
|
|
header: {
|
|
height: 40,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
backgroundColor: '#3B5998',
|
|
flexDirection: 'row',
|
|
},
|
|
text: {
|
|
color: 'white',
|
|
paddingHorizontal: 8,
|
|
},
|
|
rowText: {
|
|
color: '#888888',
|
|
},
|
|
thumbText: {
|
|
fontSize: 20,
|
|
color: '#888888',
|
|
},
|
|
buttonContents: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
marginHorizontal: 5,
|
|
marginVertical: 3,
|
|
padding: 5,
|
|
backgroundColor: '#EAEAEA',
|
|
borderRadius: 3,
|
|
paddingVertical: 10,
|
|
},
|
|
img: {
|
|
width: 64,
|
|
height: 64,
|
|
marginHorizontal: 10,
|
|
backgroundColor: 'transparent',
|
|
},
|
|
section: {
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
alignItems: 'flex-start',
|
|
padding: 6,
|
|
backgroundColor: '#5890ff',
|
|
},
|
|
});
|
|
|
|
var animations = {
|
|
layout: {
|
|
spring: {
|
|
duration: 750,
|
|
create: {
|
|
duration: 300,
|
|
type: LayoutAnimation.Types.easeInEaseOut,
|
|
property: LayoutAnimation.Properties.opacity,
|
|
},
|
|
update: {
|
|
type: LayoutAnimation.Types.spring,
|
|
springDamping: 0.4,
|
|
},
|
|
},
|
|
easeInEaseOut: {
|
|
duration: 300,
|
|
create: {
|
|
type: LayoutAnimation.Types.easeInEaseOut,
|
|
property: LayoutAnimation.Properties.scaleXY,
|
|
},
|
|
update: {
|
|
delay: 100,
|
|
type: LayoutAnimation.Types.easeInEaseOut,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
var layoutAnimationConfigs = [
|
|
animations.layout.spring,
|
|
animations.layout.easeInEaseOut,
|
|
];
|
|
|
|
module.exports = ListViewPagingExample;
|