-
Notifications
You must be signed in to change notification settings - Fork 10
/
SimpleSwiper.js
125 lines (106 loc) · 2.95 KB
/
SimpleSwiper.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
import React, { PureComponent } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
ViewPropTypes,
TouchableHighlight,
} from 'react-native';
import PropTypes from 'prop-types';
const Button = ({text,style, onPress}) => {
return (
<TouchableHighlight style={style} onPress={onPress}>
<Text>{text}</Text>
</TouchableHighlight>
)
}
export default class SimpleSwiper extends PureComponent {
static propTypes = {
/**
* 设置外部容器的样式。
*/
style: ViewPropTypes.style,
/**
* 设置外部容器的默认宽度。
*/
initialWidth: PropTypes.number,
/**
* 轮播的视图
*/
index: PropTypes.number,
/**
* 当前展现项目要变化时,触发该回调。回调参数为变化后的位置。
*/
onChange: PropTypes.func,
/**
* 轮播项目
*/
children: PropTypes.node.isRequired,
};
static defaultProps = {
initialWidth: 0,
};
constructor(props) {
super(props);
this.state = {
layoutWidth: this.props.initialWidth,
};
}
getSafeIndex = (index) => {
const max = this.props.children.length - 1;
const min = 0;
return Math.min(max, Math.max(index, min))
}
handlePress = (index) => () => {
const safeIndex = this.getSafeIndex(index);
this.props.onChange(safeIndex)
}
handleLayout = ({nativeEvent}) => {
this.setState({
layoutWidth: nativeEvent.layout.width,
})
}
render() {
const {children, style, index} = this.props;
const translateX = - index * this.state.layoutWidth;
const items = children.map((item, index) => React.cloneElement(
item,
{
key: index,
style: [
...item.props.style,
{
width: this.state.layoutWidth,
transform: [{translateX,}],
}
]
},
))
return (
<View
style={[styles.container, style]}
onLayout={this.handleLayout}
>
{items}
{/*两个测试用的按钮*/}
<Button style={[styles.button,{left: 0}]} text={'上一个'} onPress={this.handlePress(index - 1)} />
<Button style={[styles.button,{left: 50}]} text={'下一个'} onPress={this.handlePress(index + 1)} />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
overflow:'hidden',
},
button: {
position: 'absolute',
top: 120,
width: 50,
height: 20,
borderWidth: 1,
borderColor: '#ccc',
}
})