이전에 ScrollView를 이용해 캐러셀 만드는 방법에 대해서 올린 적이 있는데, FlatList를 이용해도 동일한 캐러셀을 만들 수 있다. 이번에는 FlatList를 이용해 캐러셀 만들기를 해볼 예정이다.
//ScrollViewCarousel.tsx
import styled from '@emotion/native';
import React, {useState} from 'react';
import {FlatList} from 'react-native';
const CarouselContainer = styled.View`
flex: 1;
`;
const CarouselItemContainer = styled.View`
width: ${(props: {width: number}) => props.width}px;
height: 100%;
padding: 20px;
`;
const CarouselItem = styled.View`
flex: 1;
background-color: ${(props: {color: string}) => props.color};
`;
const FlatListCarousel = () => {
const data = ['tomato', 'skyblue', 'green', 'beige', 'yellow'];
const [itemWidth, setItemWidth] = useState(0);
const renderItem = ({item}: {item: string}) => {
return (
<CarouselItemContainer key={item} width={itemWidth}>
<CarouselItem color={item} />
</CarouselItemContainer>
);
};
return (
<CarouselContainer>
<FlatList
data={data}
keyExtractor={item => item}
renderItem={renderItem}
horizontal
contentContainerStyle={{width: `${100 * data.length}%`}}
pagingEnabled
showsHorizontalScrollIndicator={false}
onContentSizeChange={w => setItemWidth(w / data.length)}
/>
</CarouselContainer>
);
};
export default FlatListCarousel;
---------------------------------------
//App.tsx
import React from 'react';
import styled from '@emotion/native';
import FlatListCarousel from './src/components/FlatListCarousel';
const AppBackground = styled.View`
justify-content: center;
align-items: center;
flex: 1;
background-color: black;
`;
const CarouselBox = styled.View`
width: 80%;
height: 60%;
border-radius: 10px;
background-color: white;
overflow: hidden;
`;
const App = () => {
return (
<AppBackground>
<CarouselBox>
<FlatListCarousel />
</CarouselBox>
</AppBackground>
);
};
export default App;
<FlatList
data={data}
keyExtractor={item => item}
renderItem={renderItem}
horizontal
contentContainerStyle={{width: `${100 * data.length}%`}}
pagingEnabled
showsHorizontalScrollIndicator={false}
onContentSizeChange={w => setItemWidth(w / data.length)}
/>
이번에도 캐러셀의 설정은 모두 FlatList 컴포넌트의 속성에서 이루어지며, 그 원리도 ScrollView와 동일하다. contentContainerStyle 속성을 통해 contentContainer의 width를 CarouselContainer의 width에 data의 길이를 곱한 만큼 주었다. 그리고 onContentSizeChange를 사용해 퍼센트로 계산된 contentContainer의 width를 정확한 px값으로 가져왔다. 이제 이렇게 받아온 width 값을 다시 캐러셀에 보여주고 싶은 data의 갯수만큼 나눠서 각 아이템의 width가 CarouselContainer에 가득 차도록 width 값을 얻어내면 가장 어려운 작업은 끝났다.
ScrollView로 구현하는 캐러셀과 비교해 다른 점이라고는 data, keyExtractor, renderItem 속성을 이용해 render를 하느냐, View 내부에 map을 사용해 직접 render하느냐의 차이일 뿐이다.