ABOUT ME

-

  • [ React Native ] FlatList + slide card
    Application/React Native 2025. 10. 15. 01:15
    반응형

    grid layout을 할려고 style을 적용해보는데 react native에는 flex: grid가 없어서 찾아보다가

    그리드 기능을 해주는 flatList를 이용


    Useage

    flatList는 가로 세로 두가지를 할 수 있으며 각각 사용법이 다르다.

     

    1. vertical

    우선 flaticon에서 해당 월의 개수만큼 박스를 만들려고해서

    해당 월의 마지막날을 data로 넣어주었다.

     

    numColums는 한 줄에 몇개를 할지 설정할 수 있다.

    이후 박스 영역 안에 넣어줘야하므로 onLayout을 이용해 박스 영역의 크기를 계산하여 박스 영역 안에 들어가는 item 박스의 크기를 계산

     

    columWrapperStyle로 각 아이템의 간격을 설정

    이후 renderItem으로 아이템 박스를 생성

    const GAP = 4; 
    const numColumns = 10;
    const itemWidth = boxWidth
            ? Math.floor((boxWidth - GAP * (numColumns - 1) - 25) / numColumns)
            : 0;
    <BoxView
                onLayout={(e) => {
                const { width } = e.nativeEvent.layout;
                setBoxWidth(width);
            }}>
                <BetweenView style={styles.btwSpace}>
                    <AppText>{prop.title}</AppText>
                    <SvgIcon name='Dot' fill/>
                </BetweenView>
                <View style={styles.metricContainer}>
                    <FlatList
                        data={Array.from({ length: daysInMonth }, (_, i) => i)}
                        keyExtractor={(item) => item.toString()}
                        numColumns={numColumns}
                        columnWrapperStyle={{ gap: GAP }}
                        renderItem={() =>
                            <View style={[styles.metric, {
                                width: itemWidth,
                                height: itemWidth,
                            }]} />
                    }
                    />
                </View>
            </BoxView>

     

    그럼 한줄에 10개인 아이템 박스가 4줄로 나오게 된다.

    여기서 style로 flex: row 를 활용하지 않고 flatList를 사용한 이유는 flex:row를 사용하다보면 양끝의 빈 공간이 문제가 생겨서 flatList를 활용했다.

     


    1. horizontal

    그럼 이제 위에 만든 박스를 여러개 만들어서 slide를 적용해서 움직일 수 있게 구현

    slide도 flatList를 활용하면 쉽게 구현할 수 있다.

     

    사용방법은 vertical과 비슷하다

    horizontal속성을 넣어주고

    showsHorizontalScrollIndicator={false}

    • UI를 깔끔하게 보이게 할 때 사용
    • 가로 스크롤을 숨겨준다.

    decelerationRate="fast"

    • 스크롤 감속 속도를 제어
    • "normal" : 기본 속도
    • "fast" : 손을 놓았을 때 더 빨리 멈춤 → 스냅 느낌 강화

    snapToInterval={ITEM_WIDTH + ITEM_SPACING}

    • 스냅 단위 거리 지정
    • FlatList가 스크롤 끝에 멈출 때 얼마만큼 이동할지 결정
    • 여기서는 “카드 하나 + 오른쪽 간격” 만큼 스크롤 → 한 번에 한 카드 단위로 멈춤

    snapToAlignment="start"

    • 스냅 위치를 시작점(왼쪽) 기준으로 맞춤
    • "center" : 스냅 위치를 카드 중앙 기준
    • "end" : 카드 오른쪽 기준
    const metrics = [
            { id: 1, component: <MetricItem title="metric 1"/>},
            { id: 2, component: <MetricItem title="metric 2"/>},
            { id: 3, component: <MetricItem title="metric 3"/>},
        ]
    return (
            <View>
                <BetweenView style={styles.btwSpace}>
                    <AppText>( {metrics.length} )</AppText>
                    <SvgIcon name='Dot' fill/>
                </BetweenView>
                <FlatList
                    data={metrics}
                    horizontal
                    showsHorizontalScrollIndicator={false}
                    decelerationRate="fast"
                    snapToInterval={ITEM_WIDTH + ITEM_SPACING} 
                    snapToAlignment="start"
                    keyExtractor={item => item.id.toString()}
                    renderItem={({item,index}) => (
                        <View style={{width: ITEM_WIDTH,
                            marginRight: index === metrics.length - 1 ? 0 : ITEM_SPACING, }}>
                            {item.component}
                        </View>
                    )}
                />
            </View>
        )

     

    그럼 스크롤하면 자연스럽게 스크롤이 되는것을 확인할 수 있다.

    728x90
    반응형