@momo-kits/swipe 0.0.74-beta → 0.72.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SwipeAction.js +673 -621
- package/SwipeActionList.js +138 -122
- package/Swiper.js +641 -570
- package/package.json +13 -13
- package/publish.sh +1 -1
package/Swiper.js
CHANGED
|
@@ -12,96 +12,96 @@
|
|
|
12
12
|
* react-native-swiper
|
|
13
13
|
* @author leecade<leecade@163.com>
|
|
14
14
|
*/
|
|
15
|
-
import React, {
|
|
15
|
+
import React, {Component} from 'react';
|
|
16
16
|
import PropTypes from 'prop-types';
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
Text,
|
|
19
|
+
View,
|
|
20
|
+
ScrollView,
|
|
21
|
+
Dimensions,
|
|
22
|
+
TouchableOpacity,
|
|
23
|
+
Platform,
|
|
24
|
+
ActivityIndicator,
|
|
25
25
|
} from 'react-native';
|
|
26
|
-
import {
|
|
26
|
+
import {ViewPager as ViewPagerAndroid} from '@momo-kits/core-v2';
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Default styles
|
|
30
30
|
* @type {StyleSheetPropType}
|
|
31
31
|
*/
|
|
32
32
|
const styles = {
|
|
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
|
-
|
|
33
|
+
container: {
|
|
34
|
+
backgroundColor: 'transparent',
|
|
35
|
+
position: 'relative',
|
|
36
|
+
flex: 1,
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
wrapperIOS: {
|
|
40
|
+
backgroundColor: 'transparent',
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
wrapperAndroid: {
|
|
44
|
+
backgroundColor: 'transparent',
|
|
45
|
+
flex: 1,
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
slide: {
|
|
49
|
+
backgroundColor: 'transparent',
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
pagination_x: {
|
|
53
|
+
position: 'absolute',
|
|
54
|
+
bottom: 25,
|
|
55
|
+
left: 0,
|
|
56
|
+
right: 0,
|
|
57
|
+
flexDirection: 'row',
|
|
58
|
+
flex: 1,
|
|
59
|
+
justifyContent: 'center',
|
|
60
|
+
alignItems: 'center',
|
|
61
|
+
backgroundColor: 'transparent',
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
pagination_y: {
|
|
65
|
+
position: 'absolute',
|
|
66
|
+
right: 15,
|
|
67
|
+
top: 0,
|
|
68
|
+
bottom: 0,
|
|
69
|
+
flexDirection: 'column',
|
|
70
|
+
flex: 1,
|
|
71
|
+
justifyContent: 'center',
|
|
72
|
+
alignItems: 'center',
|
|
73
|
+
backgroundColor: 'transparent',
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
title: {
|
|
77
|
+
height: 30,
|
|
78
|
+
justifyContent: 'center',
|
|
79
|
+
position: 'absolute',
|
|
80
|
+
paddingLeft: 10,
|
|
81
|
+
bottom: -30,
|
|
82
|
+
left: 0,
|
|
83
|
+
flexWrap: 'nowrap',
|
|
84
|
+
width: 250,
|
|
85
|
+
backgroundColor: 'transparent',
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
buttonWrapper: {
|
|
89
|
+
backgroundColor: 'transparent',
|
|
90
|
+
flexDirection: 'row',
|
|
91
|
+
position: 'absolute',
|
|
92
|
+
top: 0,
|
|
93
|
+
left: 0,
|
|
94
|
+
flex: 1,
|
|
95
|
+
paddingHorizontal: 10,
|
|
96
|
+
paddingVertical: 10,
|
|
97
|
+
justifyContent: 'space-between',
|
|
98
|
+
alignItems: 'center',
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
buttonText: {
|
|
102
|
+
fontSize: 50,
|
|
103
|
+
color: '#007aff',
|
|
104
|
+
},
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
// missing `module.exports = exports['default'];` with babel6
|
|
@@ -112,48 +112,39 @@ export default class Swiper extends Component {
|
|
|
112
112
|
* @type {Object}
|
|
113
113
|
*/
|
|
114
114
|
static propTypes = {
|
|
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
|
-
autoplayTimeout: PropTypes.number,
|
|
145
|
-
autoplayDirection: PropTypes.bool,
|
|
146
|
-
index: PropTypes.number,
|
|
147
|
-
renderPagination: PropTypes.func,
|
|
148
|
-
dotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
|
149
|
-
activeDotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
|
150
|
-
dotColor: PropTypes.string,
|
|
151
|
-
activeDotColor: PropTypes.string,
|
|
152
|
-
/**
|
|
115
|
+
horizontal: PropTypes.bool,
|
|
116
|
+
children: PropTypes.node.isRequired,
|
|
117
|
+
containerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
|
118
|
+
style: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
|
119
|
+
scrollViewStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
|
120
|
+
pagingEnabled: PropTypes.bool,
|
|
121
|
+
showsHorizontalScrollIndicator: PropTypes.bool,
|
|
122
|
+
showsVerticalScrollIndicator: PropTypes.bool,
|
|
123
|
+
bounces: PropTypes.bool,
|
|
124
|
+
scrollsToTop: PropTypes.bool,
|
|
125
|
+
removeClippedSubviews: PropTypes.bool,
|
|
126
|
+
automaticallyAdjustContentInsets: PropTypes.bool,
|
|
127
|
+
showsPagination: PropTypes.bool,
|
|
128
|
+
showsButtons: PropTypes.bool,
|
|
129
|
+
disableNextButton: PropTypes.bool,
|
|
130
|
+
loadMinimal: PropTypes.bool,
|
|
131
|
+
loadMinimalSize: PropTypes.number,
|
|
132
|
+
loadMinimalLoader: PropTypes.element,
|
|
133
|
+
loop: PropTypes.bool,
|
|
134
|
+
autoplay: PropTypes.bool,
|
|
135
|
+
autoplayTimeout: PropTypes.number,
|
|
136
|
+
autoplayDirection: PropTypes.bool,
|
|
137
|
+
index: PropTypes.number,
|
|
138
|
+
renderPagination: PropTypes.func,
|
|
139
|
+
dotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
|
140
|
+
activeDotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
|
141
|
+
dotColor: PropTypes.string,
|
|
142
|
+
activeDotColor: PropTypes.string,
|
|
143
|
+
/**
|
|
153
144
|
* Called when the index has changed because the user swiped.
|
|
154
145
|
*/
|
|
155
|
-
|
|
156
|
-
}
|
|
146
|
+
onIndexChanged: PropTypes.func,
|
|
147
|
+
};
|
|
157
148
|
|
|
158
149
|
/**
|
|
159
150
|
* Default props
|
|
@@ -161,241 +152,281 @@ export default class Swiper extends Component {
|
|
|
161
152
|
* @see http://facebook.github.io/react-native/docs/scrollview.html
|
|
162
153
|
*/
|
|
163
154
|
static defaultProps = {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
155
|
+
horizontal: true,
|
|
156
|
+
pagingEnabled: true,
|
|
157
|
+
showsHorizontalScrollIndicator: false,
|
|
158
|
+
showsVerticalScrollIndicator: false,
|
|
159
|
+
bounces: false,
|
|
160
|
+
scrollsToTop: false,
|
|
161
|
+
removeClippedSubviews: true,
|
|
162
|
+
automaticallyAdjustContentInsets: false,
|
|
163
|
+
showsPagination: true,
|
|
164
|
+
showsButtons: false,
|
|
165
|
+
disableNextButton: false,
|
|
166
|
+
loop: true,
|
|
167
|
+
loadMinimal: false,
|
|
168
|
+
loadMinimalSize: 1,
|
|
169
|
+
autoplay: false,
|
|
170
|
+
autoplayTimeout: 2.5,
|
|
171
|
+
autoplayDirection: true,
|
|
172
|
+
index: 0,
|
|
173
|
+
onIndexChanged: () => null,
|
|
174
|
+
};
|
|
184
175
|
|
|
185
176
|
/**
|
|
186
177
|
* Init states
|
|
187
178
|
* @return {object} states
|
|
188
179
|
*/
|
|
189
|
-
state = this.initState(this.props)
|
|
180
|
+
state = this.initState(this.props);
|
|
190
181
|
|
|
191
182
|
/**
|
|
192
183
|
* Initial render flag
|
|
193
184
|
* @type {bool}
|
|
194
185
|
*/
|
|
195
|
-
initialRender = true
|
|
186
|
+
initialRender = true;
|
|
196
187
|
|
|
197
188
|
/**
|
|
198
189
|
* autoplay timer
|
|
199
190
|
* @type {null}
|
|
200
191
|
*/
|
|
201
|
-
autoplayTimer = null
|
|
192
|
+
autoplayTimer = null;
|
|
202
193
|
|
|
203
|
-
loopJumpTimer = null
|
|
194
|
+
loopJumpTimer = null;
|
|
204
195
|
|
|
205
196
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
197
|
+
if (!nextProps.autoplay && this.autoplayTimer) {
|
|
198
|
+
clearTimeout(this.autoplayTimer);
|
|
199
|
+
}
|
|
200
|
+
// Fix render last item first
|
|
201
|
+
if (nextProps.index === this.props.index) return;
|
|
202
|
+
this.setState(
|
|
203
|
+
this.initState(nextProps, this.props.index !== nextProps.index),
|
|
204
|
+
);
|
|
210
205
|
}
|
|
211
206
|
|
|
212
207
|
componentDidMount() {
|
|
213
|
-
|
|
208
|
+
this.autoplay();
|
|
214
209
|
}
|
|
215
210
|
|
|
216
211
|
componentWillUnmount() {
|
|
217
|
-
|
|
218
|
-
|
|
212
|
+
this.autoplayTimer && clearTimeout(this.autoplayTimer);
|
|
213
|
+
this.loopJumpTimer && clearTimeout(this.loopJumpTimer);
|
|
219
214
|
}
|
|
220
215
|
|
|
221
216
|
UNSAFE_componentWillUpdate(nextProps, nextState) {
|
|
222
|
-
|
|
223
|
-
|
|
217
|
+
// If the index has changed, we notify the parent via the onIndexChanged callback
|
|
218
|
+
if (this.state.index !== nextState.index) {
|
|
219
|
+
this.props.onIndexChanged(nextState.index);
|
|
220
|
+
}
|
|
224
221
|
}
|
|
225
222
|
|
|
226
223
|
initState(props, updateIndex = false) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
224
|
+
// set the current state
|
|
225
|
+
const state = this.state || {
|
|
226
|
+
width: 0,
|
|
227
|
+
height: 0,
|
|
228
|
+
offset: {
|
|
229
|
+
x: 0,
|
|
230
|
+
y: 0,
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const initState = {
|
|
235
|
+
autoplayEnd: false,
|
|
236
|
+
loopJump: false,
|
|
237
|
+
offset: {},
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
initState.total = props.children ? props.children.length || 1 : 0;
|
|
241
|
+
|
|
242
|
+
if (state.total === initState.total && !updateIndex) {
|
|
239
243
|
// retain the index
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
+
initState.index = state.index;
|
|
245
|
+
} else {
|
|
246
|
+
initState.index =
|
|
247
|
+
initState.total > 1 ? Math.min(props.index, initState.total - 1) : 0;
|
|
248
|
+
}
|
|
244
249
|
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
// Default: horizontal
|
|
251
|
+
const {width, height} = Dimensions.get('window');
|
|
247
252
|
|
|
248
|
-
|
|
253
|
+
initState.dir = props.horizontal === false ? 'y' : 'x';
|
|
249
254
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
if (props.width) {
|
|
256
|
+
initState.width = props.width;
|
|
257
|
+
} else if (this.state && this.state.width) {
|
|
258
|
+
initState.width = this.state.width;
|
|
259
|
+
} else {
|
|
260
|
+
initState.width = width;
|
|
261
|
+
}
|
|
257
262
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
if (props.height) {
|
|
264
|
+
initState.height = props.height;
|
|
265
|
+
} else if (this.state && this.state.height) {
|
|
266
|
+
initState.height = this.state.height;
|
|
267
|
+
} else {
|
|
268
|
+
initState.height = height;
|
|
269
|
+
}
|
|
265
270
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
: width * props.index;
|
|
271
|
+
initState.offset[initState.dir] =
|
|
272
|
+
initState.dir === 'y' ? height * props.index : width * props.index;
|
|
269
273
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
this.internals = {
|
|
275
|
+
...this.internals,
|
|
276
|
+
isScrolling: false,
|
|
277
|
+
};
|
|
278
|
+
return initState;
|
|
275
279
|
}
|
|
276
280
|
|
|
277
281
|
// include internals with state
|
|
278
282
|
fullState() {
|
|
279
|
-
|
|
283
|
+
return {...this.state, ...this.internals};
|
|
280
284
|
}
|
|
281
285
|
|
|
282
|
-
onLayout =
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
+
onLayout = event => {
|
|
287
|
+
const {width, height} = event.nativeEvent.layout;
|
|
288
|
+
const offset = (this.internals.offset = {});
|
|
289
|
+
const state = {
|
|
290
|
+
width,
|
|
291
|
+
height,
|
|
292
|
+
};
|
|
286
293
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
offset[this.state.dir] = this.state.dir === 'y'
|
|
293
|
-
? height * setup
|
|
294
|
-
: width * setup;
|
|
294
|
+
if (this.state.total > 1) {
|
|
295
|
+
let setup = this.state.index;
|
|
296
|
+
if (this.props.loop) {
|
|
297
|
+
setup++;
|
|
295
298
|
}
|
|
299
|
+
offset[this.state.dir] =
|
|
300
|
+
this.state.dir === 'y' ? height * setup : width * setup;
|
|
301
|
+
}
|
|
296
302
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
303
|
+
// only update the offset in state if needed, updating offset while swiping
|
|
304
|
+
// causes some bad jumping / stuttering
|
|
305
|
+
if (
|
|
306
|
+
!this.state.offset ||
|
|
307
|
+
width !== this.state.width ||
|
|
308
|
+
height !== this.state.height
|
|
309
|
+
) {
|
|
310
|
+
state.offset = offset;
|
|
311
|
+
}
|
|
302
312
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
313
|
+
// related to https://github.com/leecade/react-native-swiper/issues/570
|
|
314
|
+
// contentOffset is not working in react 0.48.x so we need to use scrollTo
|
|
315
|
+
// to emulate offset.
|
|
316
|
+
if (Platform.OS === 'ios') {
|
|
317
|
+
if (this.initialRender && this.state.total > 1) {
|
|
318
|
+
this.scrollView.scrollTo({
|
|
319
|
+
...offset,
|
|
320
|
+
animated: false,
|
|
321
|
+
});
|
|
322
|
+
this.initialRender = false;
|
|
311
323
|
}
|
|
324
|
+
}
|
|
312
325
|
|
|
313
|
-
|
|
314
|
-
}
|
|
326
|
+
this.setState(state);
|
|
327
|
+
};
|
|
315
328
|
|
|
316
329
|
loopJump = () => {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
330
|
+
if (!this.state.loopJump) return;
|
|
331
|
+
const i = this.state.index + (this.props.loop ? 1 : 0);
|
|
332
|
+
const {scrollView} = this;
|
|
333
|
+
this.loopJumpTimer = setTimeout(
|
|
334
|
+
() =>
|
|
335
|
+
scrollView.setPageWithoutAnimation &&
|
|
336
|
+
scrollView.setPageWithoutAnimation(i),
|
|
337
|
+
50,
|
|
338
|
+
);
|
|
339
|
+
};
|
|
323
340
|
|
|
324
341
|
/**
|
|
325
342
|
* Automatic rolling
|
|
326
343
|
*/
|
|
327
344
|
autoplay = () => {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
this.
|
|
343
|
-
|
|
344
|
-
|
|
345
|
+
if (
|
|
346
|
+
!Array.isArray(this?.props?.children) ||
|
|
347
|
+
!this.props.autoplay ||
|
|
348
|
+
this.internals.isScrolling ||
|
|
349
|
+
this.state.autoplayEnd
|
|
350
|
+
) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
this.autoplayTimer && clearTimeout(this.autoplayTimer);
|
|
355
|
+
this.autoplayTimer = setTimeout(() => {
|
|
356
|
+
if (
|
|
357
|
+
!this.props.loop &&
|
|
358
|
+
(this.props.autoplayDirection
|
|
359
|
+
? this.state.index === this.state.total - 1
|
|
360
|
+
: this.state.index === 0)
|
|
361
|
+
) {
|
|
362
|
+
return this.setState({autoplayEnd: true});
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
this.scrollBy(this.props.autoplayDirection ? 1 : -1);
|
|
366
|
+
}, this.props.autoplayTimeout * 1000);
|
|
367
|
+
};
|
|
345
368
|
|
|
346
369
|
/**
|
|
347
370
|
* Scroll begin handle
|
|
348
371
|
* @param {object} e native event
|
|
349
372
|
*/
|
|
350
|
-
onScrollBegin =
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
373
|
+
onScrollBegin = e => {
|
|
374
|
+
// update scroll state
|
|
375
|
+
this.internals.isScrolling = true;
|
|
376
|
+
this.props.onScrollBeginDrag &&
|
|
377
|
+
this.props.onScrollBeginDrag(e, this.fullState(), this);
|
|
378
|
+
};
|
|
355
379
|
|
|
356
380
|
/**
|
|
357
381
|
* Scroll end handle
|
|
358
382
|
* @param {object} e native event
|
|
359
383
|
*/
|
|
360
|
-
onScrollEnd =
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
384
|
+
onScrollEnd = e => {
|
|
385
|
+
// update scroll state
|
|
386
|
+
this.internals.isScrolling = false;
|
|
387
|
+
|
|
388
|
+
// making our events coming from android compatible to updateIndex logic
|
|
389
|
+
if (!e.nativeEvent.contentOffset) {
|
|
390
|
+
if (this.state.dir === 'x') {
|
|
391
|
+
e.nativeEvent.contentOffset = {
|
|
392
|
+
x: e.nativeEvent.position * this.state.width,
|
|
393
|
+
};
|
|
394
|
+
} else {
|
|
395
|
+
e.nativeEvent.contentOffset = {
|
|
396
|
+
y: e.nativeEvent.position * this.state.height,
|
|
397
|
+
};
|
|
371
398
|
}
|
|
399
|
+
}
|
|
372
400
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
401
|
+
this.updateIndex(e.nativeEvent.contentOffset, this.state.dir, () => {
|
|
402
|
+
this.autoplay();
|
|
403
|
+
this.loopJump();
|
|
376
404
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
405
|
+
// if `onMomentumScrollEnd` registered will be called here
|
|
406
|
+
this.props.onMomentumScrollEnd &&
|
|
407
|
+
this.props.onMomentumScrollEnd(e, this.fullState(), this);
|
|
408
|
+
});
|
|
409
|
+
};
|
|
381
410
|
|
|
382
411
|
/*
|
|
383
412
|
* Drag end handle
|
|
384
413
|
* @param {object} e native event
|
|
385
414
|
*/
|
|
386
|
-
onScrollEndDrag =
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
415
|
+
onScrollEndDrag = e => {
|
|
416
|
+
const {contentOffset} = e.nativeEvent;
|
|
417
|
+
const {horizontal, children} = this.props;
|
|
418
|
+
const {index} = this.state;
|
|
419
|
+
const {offset} = this.internals;
|
|
420
|
+
const previousOffset = horizontal ? offset.x : offset.y;
|
|
421
|
+
const newOffset = horizontal ? contentOffset.x : contentOffset.y;
|
|
422
|
+
|
|
423
|
+
if (
|
|
424
|
+
previousOffset === newOffset &&
|
|
425
|
+
(index === 0 || index === children.length - 1)
|
|
426
|
+
) {
|
|
427
|
+
this.internals.isScrolling = false;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
399
430
|
|
|
400
431
|
/**
|
|
401
432
|
* Update index after scroll
|
|
@@ -403,61 +434,66 @@ export default class Swiper extends Component {
|
|
|
403
434
|
* @param {string} dir 'x' || 'y'
|
|
404
435
|
*/
|
|
405
436
|
updateIndex = (offset, dir, cb) => {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
437
|
+
const {state} = this;
|
|
438
|
+
let {index} = state;
|
|
439
|
+
if (!this.internals.offset) {
|
|
440
|
+
// Android not setting this onLayout first? https://github.com/leecade/react-native-swiper/issues/582
|
|
441
|
+
this.internals.offset = {};
|
|
442
|
+
}
|
|
443
|
+
const diff = offset[dir] - this.internals.offset[dir];
|
|
444
|
+
const step = dir === 'x' ? state.width : state.height;
|
|
445
|
+
let loopJump = false;
|
|
446
|
+
|
|
447
|
+
// Do nothing if offset no change.
|
|
448
|
+
if (!diff) return;
|
|
449
|
+
|
|
450
|
+
// Note: if touch very very quickly and continuous,
|
|
451
|
+
// the variation of `index` more than 1.
|
|
452
|
+
// parseInt() ensures it's always an integer
|
|
453
|
+
index = parseInt(index + Math.round(diff / step));
|
|
454
|
+
|
|
455
|
+
if (this.props.loop) {
|
|
456
|
+
if (index <= -1) {
|
|
457
|
+
index = state.total - 1;
|
|
458
|
+
offset[dir] = step * state.total;
|
|
459
|
+
loopJump = true;
|
|
460
|
+
} else if (index >= state.total) {
|
|
461
|
+
index = 0;
|
|
462
|
+
offset[dir] = step;
|
|
463
|
+
loopJump = true;
|
|
432
464
|
}
|
|
465
|
+
}
|
|
433
466
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
467
|
+
const newState = {};
|
|
468
|
+
newState.index = index;
|
|
469
|
+
newState.loopJump = loopJump;
|
|
437
470
|
|
|
438
|
-
|
|
471
|
+
this.internals.offset = offset;
|
|
439
472
|
|
|
440
|
-
|
|
441
|
-
|
|
473
|
+
// only update offset in state if loopJump is true
|
|
474
|
+
if (loopJump) {
|
|
442
475
|
// when swiping to the beginning of a looping set for the third time,
|
|
443
476
|
// the new offset will be the same as the last one set in state.
|
|
444
477
|
// Setting the offset to the same thing will not do anything,
|
|
445
478
|
// so we increment it by 1 then immediately set it to what it should be,
|
|
446
479
|
// after render.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
480
|
+
if (offset[dir] === this.internals.offset[dir]) {
|
|
481
|
+
newState.offset = {
|
|
482
|
+
x: 0,
|
|
483
|
+
y: 0,
|
|
484
|
+
};
|
|
485
|
+
newState.offset[dir] = offset[dir] + 1;
|
|
486
|
+
this.setState(newState, () => {
|
|
487
|
+
this.setState({offset}, cb);
|
|
488
|
+
});
|
|
457
489
|
} else {
|
|
458
|
-
|
|
490
|
+
newState.offset = offset;
|
|
491
|
+
this.setState(newState, cb);
|
|
459
492
|
}
|
|
460
|
-
|
|
493
|
+
} else {
|
|
494
|
+
this.setState(newState, cb);
|
|
495
|
+
}
|
|
496
|
+
};
|
|
461
497
|
|
|
462
498
|
/**
|
|
463
499
|
* Scroll by index
|
|
@@ -466,43 +502,49 @@ export default class Swiper extends Component {
|
|
|
466
502
|
*/
|
|
467
503
|
|
|
468
504
|
scrollBy = (index, animated = true) => {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
505
|
+
if (this.internals.isScrolling || this.state.total < 2) return;
|
|
506
|
+
const {state} = this;
|
|
507
|
+
const diff = (this.props.loop ? 1 : 0) + index + this.state.index;
|
|
508
|
+
let x = 0;
|
|
509
|
+
let y = 0;
|
|
510
|
+
if (state.dir === 'x') x = diff * state.width;
|
|
511
|
+
if (state.dir === 'y') y = diff * state.height;
|
|
512
|
+
|
|
513
|
+
if (Platform.OS !== 'ios') {
|
|
514
|
+
this.scrollView &&
|
|
515
|
+
this.scrollView[animated ? 'setPage' : 'setPageWithoutAnimation'](diff);
|
|
516
|
+
} else {
|
|
517
|
+
this.scrollView &&
|
|
518
|
+
this.scrollView.scrollTo({
|
|
519
|
+
x,
|
|
520
|
+
y,
|
|
521
|
+
animated,
|
|
522
|
+
});
|
|
523
|
+
}
|
|
482
524
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
525
|
+
// update scroll state
|
|
526
|
+
this.internals.isScrolling = true;
|
|
527
|
+
this.setState({
|
|
528
|
+
autoplayEnd: false,
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// trigger onScrollEnd manually in android
|
|
532
|
+
if (!animated || Platform.OS !== 'ios') {
|
|
533
|
+
setImmediate(() => {
|
|
534
|
+
this.onScrollEnd({
|
|
535
|
+
nativeEvent: {
|
|
536
|
+
position: diff,
|
|
537
|
+
},
|
|
538
|
+
});
|
|
487
539
|
});
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
if (!animated || Platform.OS !== 'ios') {
|
|
491
|
-
setImmediate(() => {
|
|
492
|
-
this.onScrollEnd({
|
|
493
|
-
nativeEvent: {
|
|
494
|
-
position: diff
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
}
|
|
540
|
+
}
|
|
541
|
+
};
|
|
500
542
|
|
|
501
543
|
scrollViewPropOverrides = () => {
|
|
502
|
-
|
|
503
|
-
|
|
544
|
+
const {props} = this;
|
|
545
|
+
const overrides = {};
|
|
504
546
|
|
|
505
|
-
|
|
547
|
+
/*
|
|
506
548
|
const scrollResponders = [
|
|
507
549
|
'onMomentumScrollBegin',
|
|
508
550
|
'onTouchStartCapture',
|
|
@@ -512,187 +554,200 @@ export default class Swiper extends Component {
|
|
|
512
554
|
]
|
|
513
555
|
*/
|
|
514
556
|
|
|
515
|
-
|
|
557
|
+
for (const prop in props) {
|
|
516
558
|
// if(~scrollResponders.indexOf(prop)
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
559
|
+
if (
|
|
560
|
+
typeof props[prop] === 'function' &&
|
|
561
|
+
prop !== 'onMomentumScrollEnd' &&
|
|
562
|
+
prop !== 'renderPagination' &&
|
|
563
|
+
prop !== 'onScrollBeginDrag'
|
|
564
|
+
) {
|
|
565
|
+
const originResponder = props[prop];
|
|
566
|
+
overrides[prop] = e => originResponder(e, this.fullState(), this);
|
|
525
567
|
}
|
|
568
|
+
}
|
|
526
569
|
|
|
527
|
-
|
|
528
|
-
}
|
|
570
|
+
return overrides;
|
|
571
|
+
};
|
|
529
572
|
|
|
530
573
|
/**
|
|
531
574
|
* Render pagination
|
|
532
575
|
* @return {object} react-dom
|
|
533
576
|
*/
|
|
534
577
|
renderPagination = () => {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const dots = [];
|
|
539
|
-
const ActiveDot = this.props.activeDot || (
|
|
540
|
-
<View style={[{
|
|
541
|
-
backgroundColor: this.props.activeDotColor || '#007aff',
|
|
542
|
-
width: 8,
|
|
543
|
-
height: 8,
|
|
544
|
-
borderRadius: 4,
|
|
545
|
-
marginLeft: 3,
|
|
546
|
-
marginRight: 3,
|
|
547
|
-
marginTop: 3,
|
|
548
|
-
marginBottom: 3
|
|
549
|
-
}, this.props.activeDotStyle]}
|
|
550
|
-
/>
|
|
551
|
-
);
|
|
552
|
-
const Dot = this.props.dot || (
|
|
553
|
-
<View style={[{
|
|
554
|
-
backgroundColor: this.props.dotColor || 'rgba(0,0,0,.2)',
|
|
555
|
-
width: 8,
|
|
556
|
-
height: 8,
|
|
557
|
-
borderRadius: 4,
|
|
558
|
-
marginLeft: 3,
|
|
559
|
-
marginRight: 3,
|
|
560
|
-
marginTop: 3,
|
|
561
|
-
marginBottom: 3
|
|
562
|
-
}, this.props.dotStyle]}
|
|
563
|
-
/>
|
|
564
|
-
);
|
|
565
|
-
for (let i = 0; i < this.state.total; i++) {
|
|
566
|
-
dots.push(i === this.state.index
|
|
567
|
-
? React.cloneElement(ActiveDot, { key: i })
|
|
568
|
-
: React.cloneElement(Dot, { key: i })
|
|
569
|
-
);
|
|
570
|
-
}
|
|
578
|
+
// By default, dots only show when `total` >= 2
|
|
579
|
+
if (this.state.total <= 1) return null;
|
|
571
580
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
581
|
+
const dots = [];
|
|
582
|
+
const ActiveDot = this.props.activeDot || (
|
|
583
|
+
<View
|
|
584
|
+
style={[
|
|
585
|
+
{
|
|
586
|
+
backgroundColor: this.props.activeDotColor || '#007aff',
|
|
587
|
+
width: 8,
|
|
588
|
+
height: 8,
|
|
589
|
+
borderRadius: 4,
|
|
590
|
+
marginLeft: 3,
|
|
591
|
+
marginRight: 3,
|
|
592
|
+
marginTop: 3,
|
|
593
|
+
marginBottom: 3,
|
|
594
|
+
},
|
|
595
|
+
this.props.activeDotStyle,
|
|
596
|
+
]}
|
|
597
|
+
/>
|
|
598
|
+
);
|
|
599
|
+
const Dot = this.props.dot || (
|
|
600
|
+
<View
|
|
601
|
+
style={[
|
|
602
|
+
{
|
|
603
|
+
backgroundColor: this.props.dotColor || 'rgba(0,0,0,.2)',
|
|
604
|
+
width: 8,
|
|
605
|
+
height: 8,
|
|
606
|
+
borderRadius: 4,
|
|
607
|
+
marginLeft: 3,
|
|
608
|
+
marginRight: 3,
|
|
609
|
+
marginTop: 3,
|
|
610
|
+
marginBottom: 3,
|
|
611
|
+
},
|
|
612
|
+
this.props.dotStyle,
|
|
613
|
+
]}
|
|
614
|
+
/>
|
|
615
|
+
);
|
|
616
|
+
for (let i = 0; i < this.state.total; i++) {
|
|
617
|
+
dots.push(
|
|
618
|
+
i === this.state.index
|
|
619
|
+
? React.cloneElement(ActiveDot, {key: i})
|
|
620
|
+
: React.cloneElement(Dot, {key: i}),
|
|
576
621
|
);
|
|
577
|
-
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return (
|
|
625
|
+
<View
|
|
626
|
+
pointerEvents="none"
|
|
627
|
+
style={[
|
|
628
|
+
styles[`pagination_${this.state.dir}`],
|
|
629
|
+
this.props.paginationStyle,
|
|
630
|
+
]}>
|
|
631
|
+
{dots}
|
|
632
|
+
</View>
|
|
633
|
+
);
|
|
634
|
+
};
|
|
578
635
|
|
|
579
636
|
renderTitle = () => {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
637
|
+
let {children = []} = this.props;
|
|
638
|
+
const child = children[this.state.index];
|
|
639
|
+
const title = child && child.props && child.props.title;
|
|
640
|
+
return !!title ? (
|
|
641
|
+
<View style={styles.title}>
|
|
642
|
+
{this.props.children?.[this.state.index].props.title}
|
|
643
|
+
</View>
|
|
644
|
+
) : null;
|
|
645
|
+
};
|
|
590
646
|
|
|
591
647
|
renderNextButton = () => {
|
|
592
|
-
|
|
648
|
+
let button = null;
|
|
593
649
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
return (
|
|
600
|
-
<TouchableOpacity
|
|
601
|
-
onPress={() => button !== null && this.scrollBy(1)}
|
|
602
|
-
disabled={this.props.disableNextButton}
|
|
603
|
-
>
|
|
604
|
-
<View>
|
|
605
|
-
{button}
|
|
606
|
-
</View>
|
|
607
|
-
</TouchableOpacity>
|
|
650
|
+
if (this.props.loop || this.state.index !== this.state.total - 1) {
|
|
651
|
+
button = this.props.nextButton || (
|
|
652
|
+
<Text style={styles.buttonText}>›</Text>
|
|
608
653
|
);
|
|
609
|
-
|
|
654
|
+
}
|
|
610
655
|
|
|
611
|
-
|
|
612
|
-
|
|
656
|
+
return (
|
|
657
|
+
<TouchableOpacity
|
|
658
|
+
onPress={() => button !== null && this.scrollBy(1)}
|
|
659
|
+
disabled={this.props.disableNextButton}>
|
|
660
|
+
<View>{button}</View>
|
|
661
|
+
</TouchableOpacity>
|
|
662
|
+
);
|
|
663
|
+
};
|
|
613
664
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
}
|
|
665
|
+
renderPrevButton = () => {
|
|
666
|
+
let button = null;
|
|
617
667
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
{button}
|
|
622
|
-
</View>
|
|
623
|
-
</TouchableOpacity>
|
|
668
|
+
if (this.props.loop || this.state.index !== 0) {
|
|
669
|
+
button = this.props.prevButton || (
|
|
670
|
+
<Text style={styles.buttonText}>‹</Text>
|
|
624
671
|
);
|
|
625
|
-
|
|
672
|
+
}
|
|
626
673
|
|
|
627
|
-
|
|
628
|
-
<
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
}, this.props.buttonWrapperStyle]}
|
|
634
|
-
>
|
|
635
|
-
{this.renderPrevButton()}
|
|
636
|
-
{this.renderNextButton()}
|
|
637
|
-
</View>
|
|
638
|
-
)
|
|
674
|
+
return (
|
|
675
|
+
<TouchableOpacity onPress={() => button !== null && this.scrollBy(-1)}>
|
|
676
|
+
<View>{button}</View>
|
|
677
|
+
</TouchableOpacity>
|
|
678
|
+
);
|
|
679
|
+
};
|
|
639
680
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
681
|
+
renderButtons = () => (
|
|
682
|
+
<View
|
|
683
|
+
pointerEvents="box-none"
|
|
684
|
+
style={[
|
|
685
|
+
styles.buttonWrapper,
|
|
686
|
+
{
|
|
687
|
+
width: this.state.width,
|
|
688
|
+
height: this.state.height,
|
|
689
|
+
},
|
|
690
|
+
this.props.buttonWrapperStyle,
|
|
691
|
+
]}>
|
|
692
|
+
{this.renderPrevButton()}
|
|
693
|
+
{this.renderNextButton()}
|
|
694
|
+
</View>
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
refScrollView = view => {
|
|
698
|
+
this.scrollView = view;
|
|
699
|
+
};
|
|
643
700
|
|
|
644
|
-
onPageScrollStateChanged =
|
|
645
|
-
|
|
701
|
+
onPageScrollStateChanged = state => {
|
|
702
|
+
switch (state) {
|
|
646
703
|
case 'dragging':
|
|
647
|
-
|
|
704
|
+
return this.onScrollBegin();
|
|
648
705
|
|
|
649
706
|
case 'idle':
|
|
650
707
|
case 'settling':
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
708
|
+
if (this.props.onTouchEnd) this.props.onTouchEnd();
|
|
709
|
+
}
|
|
710
|
+
};
|
|
654
711
|
|
|
655
|
-
renderScrollView =
|
|
656
|
-
|
|
657
|
-
return (
|
|
658
|
-
<ScrollView
|
|
659
|
-
ref={this.refScrollView}
|
|
660
|
-
{...this.props}
|
|
661
|
-
{...this.scrollViewPropOverrides()}
|
|
662
|
-
contentContainerStyle={[styles.wrapperIOS, this.props.style]}
|
|
663
|
-
contentOffset={this.state.offset}
|
|
664
|
-
onScrollBeginDrag={this.onScrollBegin}
|
|
665
|
-
onMomentumScrollEnd={this.onScrollEnd}
|
|
666
|
-
onScrollEndDrag={this.onScrollEndDrag}
|
|
667
|
-
style={this.props.scrollViewStyle}
|
|
668
|
-
>
|
|
669
|
-
{pages}
|
|
670
|
-
</ScrollView>
|
|
671
|
-
);
|
|
672
|
-
}
|
|
712
|
+
renderScrollView = pages => {
|
|
713
|
+
if (Platform.OS === 'ios') {
|
|
673
714
|
return (
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
715
|
+
<ScrollView
|
|
716
|
+
ref={this.refScrollView}
|
|
717
|
+
{...this.props}
|
|
718
|
+
{...this.scrollViewPropOverrides()}
|
|
719
|
+
contentContainerStyle={[styles.wrapperIOS, this.props.style]}
|
|
720
|
+
contentOffset={this.state.offset}
|
|
721
|
+
onScrollBeginDrag={this.onScrollBegin}
|
|
722
|
+
onMomentumScrollEnd={this.onScrollEnd}
|
|
723
|
+
onScrollEndDrag={this.onScrollEndDrag}
|
|
724
|
+
style={this.props.scrollViewStyle}>
|
|
725
|
+
{pages}
|
|
726
|
+
</ScrollView>
|
|
685
727
|
);
|
|
686
|
-
|
|
728
|
+
}
|
|
729
|
+
return (
|
|
730
|
+
<ViewPagerAndroid
|
|
731
|
+
ref={this.refScrollView}
|
|
732
|
+
{...this.props}
|
|
733
|
+
initialPage={this.props.loop ? this.state.index + 1 : this.state.index}
|
|
734
|
+
onPageScrollStateChanged={this.onPageScrollStateChanged}
|
|
735
|
+
onPageSelected={this.onScrollEnd}
|
|
736
|
+
key={pages.length}
|
|
737
|
+
style={[styles.wrapperAndroid, this.props.style]}>
|
|
738
|
+
{pages}
|
|
739
|
+
</ViewPagerAndroid>
|
|
740
|
+
);
|
|
741
|
+
};
|
|
687
742
|
|
|
688
|
-
checkPagesBeforeAfter =
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}
|
|
743
|
+
checkPagesBeforeAfter = children => {
|
|
744
|
+
let str = '';
|
|
745
|
+
if (children && Array.isArray(children)) {
|
|
746
|
+
for (const child in children) {
|
|
747
|
+
str += children[child].key || child;
|
|
694
748
|
}
|
|
695
|
-
|
|
749
|
+
}
|
|
750
|
+
return str;
|
|
696
751
|
};
|
|
697
752
|
|
|
698
753
|
/**
|
|
@@ -700,75 +755,91 @@ export default class Swiper extends Component {
|
|
|
700
755
|
* @return {object} react-dom
|
|
701
756
|
*/
|
|
702
757
|
render() {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
758
|
+
const {index, total, width, height} = this.state;
|
|
759
|
+
const {
|
|
760
|
+
children,
|
|
761
|
+
containerStyle,
|
|
762
|
+
loop,
|
|
763
|
+
loadMinimal,
|
|
764
|
+
loadMinimalSize,
|
|
765
|
+
loadMinimalLoader,
|
|
766
|
+
renderPagination,
|
|
767
|
+
showsButtons,
|
|
768
|
+
showsPagination,
|
|
769
|
+
} = this.props;
|
|
770
|
+
// let dir = state.dir
|
|
771
|
+
// let key = 0
|
|
772
|
+
const loopVal = loop ? 1 : 0;
|
|
773
|
+
let pages = [];
|
|
774
|
+
|
|
775
|
+
const pageStyle = [
|
|
776
|
+
{
|
|
777
|
+
width,
|
|
778
|
+
height,
|
|
779
|
+
},
|
|
780
|
+
styles.slide,
|
|
781
|
+
];
|
|
782
|
+
const pageStyleLoading = {
|
|
783
|
+
width,
|
|
784
|
+
height,
|
|
785
|
+
flex: 1,
|
|
786
|
+
justifyContent: 'center',
|
|
787
|
+
alignItems: 'center',
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
// For make infinite at least total > 1
|
|
791
|
+
if (total > 1) {
|
|
736
792
|
// Re-design a loop model for avoid img flickering
|
|
737
|
-
|
|
738
|
-
|
|
793
|
+
pages = Object.keys(children);
|
|
794
|
+
// console.log(`checkPagesBeforeAfter children: ${JSON.stringify(this.checkPagesBeforeAfter(pages))}`);
|
|
739
795
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
pages = pages.map((page, i) => {
|
|
746
|
-
if (loadMinimal) {
|
|
747
|
-
if (i >= (index + loopVal - loadMinimalSize)
|
|
748
|
-
&& i <= (index + loopVal + loadMinimalSize)) {
|
|
749
|
-
return <View style={pageStyle} key={i}>{children[page]}</View>;
|
|
750
|
-
}
|
|
751
|
-
return (
|
|
752
|
-
<View style={pageStyleLoading} key={i}>
|
|
753
|
-
{loadMinimalLoader || <ActivityIndicator />}
|
|
754
|
-
</View>
|
|
755
|
-
);
|
|
756
|
-
}
|
|
757
|
-
return <View style={pageStyle} key={i}>{children[page]}</View>;
|
|
758
|
-
});
|
|
759
|
-
} else {
|
|
760
|
-
pages = <View style={pageStyle} key={0}>{children}</View>;
|
|
796
|
+
if (loop) {
|
|
797
|
+
pages.unshift(`${total - 1}`);
|
|
798
|
+
pages.push('0');
|
|
761
799
|
}
|
|
762
800
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
{
|
|
801
|
+
pages = pages.map((page, i) => {
|
|
802
|
+
if (loadMinimal) {
|
|
803
|
+
if (
|
|
804
|
+
i >= index + loopVal - loadMinimalSize &&
|
|
805
|
+
i <= index + loopVal + loadMinimalSize
|
|
806
|
+
) {
|
|
807
|
+
return (
|
|
808
|
+
<View style={pageStyle} key={i}>
|
|
809
|
+
{children[page]}
|
|
810
|
+
</View>
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
return (
|
|
814
|
+
<View style={pageStyleLoading} key={i}>
|
|
815
|
+
{loadMinimalLoader || <ActivityIndicator />}
|
|
816
|
+
</View>
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
return (
|
|
820
|
+
<View style={pageStyle} key={i}>
|
|
821
|
+
{children[page]}
|
|
771
822
|
</View>
|
|
823
|
+
);
|
|
824
|
+
});
|
|
825
|
+
} else {
|
|
826
|
+
pages = (
|
|
827
|
+
<View style={pageStyle} key={0}>
|
|
828
|
+
{children}
|
|
829
|
+
</View>
|
|
772
830
|
);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
return (
|
|
834
|
+
<View style={[styles.container, containerStyle]} onLayout={this.onLayout}>
|
|
835
|
+
{this.renderScrollView(pages)}
|
|
836
|
+
{showsPagination &&
|
|
837
|
+
(renderPagination
|
|
838
|
+
? renderPagination(index, total, this)
|
|
839
|
+
: this.renderPagination())}
|
|
840
|
+
{this.renderTitle()}
|
|
841
|
+
{showsButtons && this.renderButtons()}
|
|
842
|
+
</View>
|
|
843
|
+
);
|
|
773
844
|
}
|
|
774
845
|
}
|