-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
122 lines (111 loc) · 3.22 KB
/
index.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
import React, { Component, PropTypes } from 'react'
import {
StyleSheet,
View,
ListView,
Text,
TouchableOpacity,
PanResponder,
} from 'react-native'
import _ from 'lodash'
export default class StickySearchList extends Component {
constructor(props) {
super(props);
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: this.onShouldSetPanResponder.bind(this),
onMoveShouldSetPanResponder: this.onShouldSetPanResponder.bind(this),
onPanResponderMove: this.onPanResponderMove.bind(this),
})
this.dataSource = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 })
}
onShouldSetPanResponder (e, gesture) {
return true
}
onPanResponderMove (e, gesture) {
const py = e.nativeEvent.pageY - 50
const px = e.nativeEvent.locationX
const index = Math.floor(py / 30)
const { data, searchBarWidth = 20 } = this.props
if (px > 0 & px < searchBarWidth) {
if (index < data.length) {
this.listView.scrollTo({y: this[`offsetYFor${_.keys(data[index])[0]}`], animated: false})
}
}
}
_renderRow (data, sectionID, rowID, highlightRow) {
return (
<View onLayout={this._onCellLayout.bind(this, rowID)}>
{this.props.renderRow(data, sectionID, rowID, highlightRow)}
</View>
)
}
_onCellLayout (index, event) {
const { data } = this.props
this[`offsetYFor${_.keys(data[index])[0]}`] = event.nativeEvent.layout.y
}
_handleSwitch (index) {
const { data } = this.props
this.listView.scrollTo({y: this[`offsetYFor${_.keys(data[index])[0]}`], animated: false})
}
render () {
const {
data,
searchBarBackgroundColor,
searchBarWidth,
searchBarTextStyle,
} = this.props
return (
<View style={styles.container}>
<ListView
ref={ lv => this.listView = lv}
dataSource={this.dataSource.cloneWithRows(data)}
renderRow={this._renderRow.bind(this)}
/>
<View
{...this.panResponder.panHandlers}
style={[
styles.searchBar,
searchBarBackgroundColor ? { backgroundColor: searchBarBackgroundColor } : {},
searchBarWidth ? { width: searchBarWidth } : {}
]}
>
{
data.map((item, index) => (
<TouchableOpacity onPress={this._handleSwitch.bind(this, index)} key={index} style={styles.searchBarItem}>
<Text style={[{ fontSize: 18 }, searchBarTextStyle]}>{_.keys(item)[0]}</Text>
</TouchableOpacity>)
)
}
</View>
</View>
)
}
}
StickySearchList.propTypes = {
data: PropTypes.arrayOf(PropTypes.object),
searchBarBackgroundColor: PropTypes.string,
searchBarWidth: PropTypes.number,
searchBarTextStyle: PropTypes.object,
renderRow: PropTypes.func.isRequired,
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
searchBar: {
width: 20,
position: 'absolute',
top: 50,
right: 10,
borderRadius: 5,
backgroundColor: 'rgba(0, 0, 0, 0.6)',
},
searchBarItem: {
height: 30,
justifyContent: 'center',
alignItems: 'center',
},
})