-
Notifications
You must be signed in to change notification settings - Fork 24.2k
/
MultiColumnExample.js
154 lines (145 loc) · 4.42 KB
/
MultiColumnExample.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* 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.
*
* @flow
* @providesModule MultiColumnExample
*/
'use strict';
const React = require('react');
const ReactNative = require('react-native');
const {
FlatList,
StyleSheet,
Text,
View,
} = ReactNative;
const RNTesterPage = require('./RNTesterPage');
const infoLog = require('infoLog');
const {
FooterComponent,
HeaderComponent,
ItemComponent,
PlainInput,
SeparatorComponent,
genItemData,
getItemLayout,
pressItem,
renderSmallSwitchOption,
} = require('./ListExampleShared');
class MultiColumnExample extends React.PureComponent<$FlowFixMeProps, $FlowFixMeState> {
static title = '<FlatList> - MultiColumn';
static description = 'Performant, scrollable grid of data.';
state = {
data: genItemData(1000),
filterText: '',
fixedHeight: true,
logViewable: false,
numColumns: 2,
virtualized: true,
};
_onChangeFilterText = (filterText) => {
this.setState(() => ({filterText}));
};
_onChangeNumColumns = (numColumns) => {
this.setState(() => ({numColumns: Number(numColumns)}));
};
render() {
const filterRegex = new RegExp(String(this.state.filterText), 'i');
const filter = (item) => (filterRegex.test(item.text) || filterRegex.test(item.title));
const filteredData = this.state.data.filter(filter);
return (
<RNTesterPage
title={this.props.navigator ? null : '<FlatList> - MultiColumn'}
noSpacer={true}
noScroll={true}>
<View style={styles.searchRow}>
<View style={styles.row}>
<PlainInput
onChangeText={this._onChangeFilterText}
placeholder="Search..."
value={this.state.filterText}
/>
<Text> numColumns: </Text>
<PlainInput
clearButtonMode="never"
onChangeText={this._onChangeNumColumns}
value={this.state.numColumns ? String(this.state.numColumns) : ''}
/>
</View>
<View style={styles.row}>
{renderSmallSwitchOption(this, 'virtualized')}
{renderSmallSwitchOption(this, 'fixedHeight')}
{renderSmallSwitchOption(this, 'logViewable')}
</View>
</View>
<SeparatorComponent />
<FlatList
ListFooterComponent={FooterComponent}
ListHeaderComponent={HeaderComponent}
getItemLayout={this.state.fixedHeight ? this._getItemLayout : undefined}
data={filteredData}
key={this.state.numColumns + (this.state.fixedHeight ? 'f' : 'v')}
numColumns={this.state.numColumns || 1}
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
refreshing={false}
renderItem={this._renderItemComponent}
disableVirtualization={!this.state.virtualized}
onViewableItemsChanged={this._onViewableItemsChanged}
legacyImplementation={false}
/>
</RNTesterPage>
);
}
_getItemLayout(data: any, index: number): {length: number, offset: number, index: number} {
const length = getItemLayout(data, index).length + 2 * (CARD_MARGIN + BORDER_WIDTH);
return {length, offset: length * index, index};
}
_renderItemComponent = ({item}) => {
return (
<View style={styles.card}>
<ItemComponent
item={item}
fixedHeight={this.state.fixedHeight}
onPress={this._pressItem}
/>
</View>
);
};
// This is called when items change viewability by scrolling into or out of the viewable area.
_onViewableItemsChanged = (info: {
changed: Array<{
key: string, isViewable: boolean, item: {columns: Array<*>}, index: ?number, section?: any
}>},
) => {
// Impressions can be logged here
if (this.state.logViewable) {
infoLog('onViewableItemsChanged: ', info.changed.map((v) => ({...v, item: '...'})));
}
};
_pressItem = (key: string) => {
pressItem(this, key);
};
}
const CARD_MARGIN = 4;
const BORDER_WIDTH = 1;
const styles = StyleSheet.create({
card: {
margin: CARD_MARGIN,
borderRadius: 10,
flex: 1,
overflow: 'hidden',
borderColor: 'lightgray',
borderWidth: BORDER_WIDTH,
},
row: {
flexDirection: 'row',
alignItems: 'center',
},
searchRow: {
padding: 10,
},
});
module.exports = MultiColumnExample;