Skip to content

Commit 596ee30

Browse files
ethansharInbal-Tish
authored andcommitted
support dynamic width for Carousel (#557)
* support dynamic width for Carousel * improve full page carousel example * declare on containerWidth in Carousel
1 parent ebee94a commit 596ee30

File tree

2 files changed

+68
-17
lines changed

2 files changed

+68
-17
lines changed

demo/src/screens/componentScreens/CarouselScreen.js

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import React, {Component} from 'react';
22
import {StyleSheet} from 'react-native';
3-
import {Constants, View, Text, Carousel} from 'react-native-ui-lib'; // eslint-disable-line
4-
3+
import {Constants, View, Text, Carousel, Image, Card} from 'react-native-ui-lib'; // eslint-disable-line
4+
import _ from 'lodash';
55

66
const INITIAL_PAGE = 0;
77
const WIDTH = Constants.screenWidth - 120;
88

9+
const IMAGES = [
10+
'https://images.pexels.com/photos/1212487/pexels-photo-1212487.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
11+
'https://images.pexels.com/photos/1366630/pexels-photo-1366630.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
12+
'https://images.pexels.com/photos/1477459/pexels-photo-1477459.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
13+
'https://images.pexels.com/photos/60597/dahlia-red-blossom-bloom-60597.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
14+
];
15+
916
class CarouselScreen extends Component {
1017
state = {
1118
currentPage: INITIAL_PAGE
@@ -15,23 +22,25 @@ class CarouselScreen extends Component {
1522
this.setState({currentPage: index});
1623
}
1724

18-
onPagePress = (index) => {
25+
onPagePress = index => {
1926
this.carousel.goToPage(index, true);
20-
}
27+
};
2128

2229
render() {
2330
return (
2431
<View flex>
25-
<Text text30 margin-20>Carousel</Text>
26-
<Carousel
27-
migrate
28-
ref={r => this.carousel = r}
29-
// loop
30-
onChangePage={(index => this.onChangePage(index))}
32+
<Text text30 margin-20>
33+
Carousel
34+
</Text>
35+
<Carousel
36+
migrate
37+
ref={r => (this.carousel = r)}
38+
// loop
39+
onChangePage={index => this.onChangePage(index)}
3140
pageWidth={WIDTH}
3241
// itemSpacings={20}
3342
// initialPage={INITIAL_PAGE}
34-
containerStyle={{height: 200/* , flex: 1 */}}
43+
containerStyle={{height: 160/* , flex: 1 */}}
3544
pageControlPosition={'under'}
3645
pageControlProps={{onPagePress: this.onPagePress}}
3746
// showCounter
@@ -58,10 +67,28 @@ class CarouselScreen extends Component {
5867
<Text margin-15>PAGE 6</Text>
5968
</Page>
6069
</Carousel>
61-
70+
6271
<View margin-20 center /*style={{...StyleSheet.absoluteFillObject}} */ pointerEvents="none">
6372
<Text text10>{this.state.currentPage}</Text>
6473
</View>
74+
75+
<View padding-20>
76+
<Carousel test migrate containerStyle={{height: 160}}>
77+
{_.map(IMAGES, (image, index) => {
78+
return (
79+
<View key={index} flex padding-10 bottom>
80+
<Image
81+
style={StyleSheet.absoluteFillObject}
82+
source={{
83+
uri: image
84+
}}
85+
/>
86+
<Text white text50>Image {index}</Text>
87+
</View>
88+
);
89+
})}
90+
</Carousel>
91+
</View>
6592
</View>
6693
);
6794
}

src/components/carousel/index.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export default class Carousel extends BaseComponent {
8989
: props.pageWidth + props.itemSpacings || Constants.screenWidth;
9090

9191
this.state = {
92+
containerWidth: undefined,
9293
currentPage: this.shouldUsePageWidth() ? this.getCalcIndex(props.initialPage) : props.initialPage,
9394
currentStandingPage: props.initialPage,
9495
pageWidth: defaultPageWidth,
@@ -145,11 +146,31 @@ export default class Carousel extends BaseComponent {
145146
return index;
146147
}
147148

149+
getSnapToOffsets = () => {
150+
const {itemSpacings} = this.props;
151+
const {containerWidth, pageWidth} = this.state;
152+
153+
if (containerWidth) {
154+
const spacings = pageWidth === containerWidth ? 0 : itemSpacings;
155+
const initialBreak = pageWidth - (containerWidth - pageWidth - spacings) / 2;
156+
const snapToOffsets = _.times(presenter.getChildrenLength(this.props), index => initialBreak + index * pageWidth);
157+
return snapToOffsets;
158+
}
159+
}
160+
148161
shouldUsePageWidth() {
149162
const {loop, pageWidth} = this.props;
150163
return !loop && pageWidth;
151164
}
152165

166+
onContainerLayout = ({nativeEvent: {layout: {width: containerWidth}}}) => {
167+
const update = {containerWidth};
168+
if (!this.props.pageWidth) {
169+
update.pageWidth = containerWidth;
170+
}
171+
this.setState(update);
172+
}
173+
153174
onContentSizeChange = () => {
154175
// this is to handle initial scroll position (content offset)
155176
if (Constants.isAndroid) {
@@ -200,6 +221,11 @@ export default class Carousel extends BaseComponent {
200221
};
201222

202223
renderChildren() {
224+
const {containerWidth} = this.state;
225+
if (!containerWidth && !this.shouldUsePageWidth()) {
226+
return null;
227+
}
228+
203229
const {children, loop} = this.props;
204230
const length = presenter.getChildrenLength(this.props);
205231

@@ -257,15 +283,13 @@ export default class Carousel extends BaseComponent {
257283

258284
render() {
259285
const {containerStyle, itemSpacings, ...others} = this.props;
260-
const {initialOffset, pageWidth} = this.state;
286+
const {initialOffset} = this.state;
261287

262288
const scrollContainerStyle = this.shouldUsePageWidth() ? {paddingRight: itemSpacings} : undefined;
263-
const spacings = pageWidth === Constants.screenWidth ? 0 : itemSpacings;
264-
const initialBreak = pageWidth - (Constants.screenWidth - pageWidth - spacings) / 2;
265-
const snapToOffsets = _.times(presenter.getChildrenLength(this.props), index => initialBreak + index * pageWidth);
289+
const snapToOffsets = this.getSnapToOffsets();
266290

267291
return (
268-
<View style={containerStyle}>
292+
<View style={containerStyle} onLayout={this.onContainerLayout}>
269293
<ScrollView
270294
{...others}
271295
ref={this.carousel}

0 commit comments

Comments
 (0)