-
React Native: Scrollable Tab View 구현하기개발/리액트 네이티브 2021. 1. 19. 13:43
탭 관련 라이브러리 없이 javascript와 react hooks로 스크롤러블 탭 뷰를 구현해보는게 목표.
구현 해보고 싶은 2가지 기능:
1. 탭 지원
2. 탭 뷰 스크롤 제스쳐 지원
3. 탭 메뉴 애니메이션 처리
일단 탭 컴포넌트를 만들어서 사용할 때는 간단하게 사용하고 싶었다.
<ScrollableTab tabBarUnderlineStyle={BodocBlue} renderTabBar={() => <ScrollableTabBar />}> <Page1 tabLabel="One" /> <Page2 tabLabel="Two" /> <Page3 tabLabel="Three" /> </ScrollableTab>
크게 부모 탭 컴포넌트가 감싸고 자식으로는 탭뷰를 넣는 구조가 좋을 것 같다고 생각했다.
그럴라면 일단 필수적으로 React.Child를 활용해야했다.
<ScrollableTab>에서 React.FC로 children 받으므로 children을 활용해보자!
탭 뷰 구성하는 함수 만들기:
탭 뷰를 구성하는 작은 단위의 함수를 만들어주었다.
<ScrollableTab /> 안에 들어있는 Child만큼 반복문을 돌려주며, 키 값을 만들어준 뒤 <TabView />를 반환 시켜준다.
const composeTabView = () => { return React.Children.map(children, (chlid, idx)=>{ let key = makeTabViewKey(child, idx); return <TabView key={key} style={{width: containerWidth}}>{child}</TabView> } }
탭 매뉴, 탭 뷰를 렌더링하기:
composeTabView()를 통해 나온 리턴값을 tabview 변수에 담아주고 최종적으로 탭뷰를 렌더링하는 함수를 만들어주었다.
첫 번째는 renderTabBar()와 renderTabView() 2가지의 그 다음 작은 단위의 함수를 만들어주는 것이다.
// 탭 const renderTabBar = (props) => { return <DefaultTabBar {...props} />; }; // 탭뷰 const renderTabView = () => { const tabview = composeTabView(); return ( <Animated.ScrollView ref={TabViewRef} horizontal pagingEnabled onScroll={Animated.event([{ nativeEvent: { contentOffset: { x: scrollX } } }], { useNativeDriver: true })} keyboardDismissMode="on-drag" scrollEventThrottle={16} directionalLockEnabled> {tabview} </Animated.ScrollView> ); };
렌더:
[...] return ( <View ref={contentView} style={{ flex: 1 }} onLayout={(e: any) => handleLayout(e)}> {renderTabBar(tabBarProps)} {renderTabView()} </View> ); [...]
renderTabBar()에 들어가는 인자값으로 탭 매뉴를 구성하는 프롭스를 객체로 보내주었다.
만든 객체에 추가되는 속성을 넣어주면서 속성을 관리해주었다.
// 탭 바를 이루는 프롭스 let tabBarProps = { goToPage: goToPage, tabs: React.Children.map(children, (child: React.ReactNode) => child?.props.tabLabel), activeTab: currentPage, setCurrentPage: setCurrentPage, scrollX: scrollX, scrollValue: scrollValue, containerWidth: containerWidth, }; // 탭 매뉴 배경 속성 if (tabBarBackgroundColor) { tabBarProps.backgroundColor = tabBarBackgroundColor; } // 탭 매뉴 활성화 시 텍스트 색상 속성 if (tabBarActiveTextColor) { tabBarProps.activeTextColor = tabBarActiveTextColor; } else { tabBarProps.activeTextColor = BodocBlue; } // 탭 매뉴 비활성화 시 텍스트 색상 속성 if (tabBarInactiveTextColor) { tabBarProps.inactiveTextColor = tabBarInactiveTextColor; } else { tabBarProps.inactiveTextColor = BodocGray; } // 탭 매뉴 텍스트 스타일 속성 if (tabBarTextStyle) { tabBarProps.textStyle = tabBarTextStyle; } // 탭 메뉴 언더바 스타일 속성 if (tabBarUnderlineStyle) { tabBarProps.underlineStyle = tabBarUnderLineStyle; } else { tabBarProps.underlineStyle = BodocBlue; }
이러한 속성은 실제적으로 <ScrollableTab /> 태그에 계속 추가해주면서 사용할 수 있게 된다.:
결과
보완해야 할 점과 느낀점:
스크롤 탭 UI를 개발하면서 React 최상위 API를 학습하는 좋은 계기가 되었다.
조금 더 소스를 최적화 해보는 작업을 하면서 메뉴 탭 애니메이션 처리를 보완할 예정이다.
그리고 defaultTabBar말고 스크롤되는 TabBar도 추가할 것이다.
+ 탭 메뉴 애니메이션 추가:
const tabUnderlineStyle: any = { position: 'absolute', width: containerWidth / numberOfTabs, height: 4, backgroundColor: activeTextColor, bottom: 0, };
const left = scrollValue.interpolate({ inputRange: [0, 1], outputRange: [0, containerWidth / numberOfTabs], });
'개발 > 리액트 네이티브' 카테고리의 다른 글
React Native: FlatList 스크롤이 안되는 현상 (0) 2021.02.04 No bundle url present 이슈 해결 (0) 2021.01.21 React Native: pod install error 해결 방법 (0) 2021.01.16 React Native: 싸인 기능 구현하기 (0) 2021.01.15 React Native: 카메라 스캔 영역 지정하기 camera scan limit area (0) 2021.01.15