티스토리 뷰
1. 이번 포스팅의 목적
Bottom-Tab Navigator가 메인화면에 있고,
어떤 Tab을 누르면(또는 어떤 Component를 누르면) 하단 탭 없이 화면을 전체 다 덮게 뜨게 하고 싶을 수 있다.
(예를 들어보자면, 쿠팡앱에서 하단 탭에 "검색"을 누를 때, 메인에서 상품 하나를 눌렀을 때 등)
이때, navigation을 어떤 식으로 구성하면 되는지 알아보자.
예제는
styled-component, 반응형디자인([React Native] 10. 반응형 디자인 적용하기) 을 사용했습니다.
2. Bottom Tab Navigator 구성
Bottom Tab Navigator는 이전 포스팅_[React-Native] 8. Bottom Tab Navigator 사용하기_의 예제를 사용한다.
이전 포스팅에서, 아래와 같은 화면을 만들었었다.

위 화면에서, "카테고리" 탭을 눌렀을 때 하단탭이 없는 새로운 화면을 띄워보자.
3. Stack Navigator 구성
1) 우선, "카테고리" 탭을 눌렀을 때 나타날 화면으로 "NewScreen"이란 Component를 만들어준다.
(styled-component 사용-Placeholder 정의)
const Placeholder = Styled.View`
width: ${widthPercentage(360)}px;
height: ${ScreenHeight + StatusHeight}px;
paddingLeft: ${widthPercentage(155)}px;
paddingTop: ${heightPercentage(360)}px;
background-color: #FFFF11;
`;
const NewScreen = () => {
return (
<Placeholder style={{ backgroundColor: "#FF1111" }}>
<Text>New Screen</Text>
</Placeholder>
);
};
2) Stack Navigator를 정의한다.
import { createStackNavigator, StackNavigationProp } from "@react-navigation/stack";
const Stack = createStackNavigator();
const WholeStack = () => {
return (
<Stack.Navigator initialRouteName="TabNavi">
<Stack.Screen
name="TabNavi"
component={TabNavi}
options={{ headerShown: false, animationEnabled: false }}
/>
<Stack.Screen
name="NewScreen"
component={NewScreen}
options={{ headerShown: false, animationEnabled: false }}
/>
</Stack.Navigator>
);
};
export default () => {
return (
<NavigationContainer>
<WholeStack />
</NavigationContainer>
);
};
첫 번째 Stack.Screen은 이전 포스팅에서 만든 Bottom Tab Navigator로,
두 번째 Stack.Screen은 위에서 만든 NewScreen(탭을 눌렀을 때 띄우고 싶은 화면)이란 component로 설정해준다.
→ 여기서 options 중 headerShown은 상단 Navigation header를 띄울 것인지, animationEnable은 화면을 전환할 때 애니메이션 효과를 보여줄 것인지를 각각 의미한다.
Stack.Navigator의 prop에 initialRouteName="TabNavi"로 지정해
제일 첫 화면엔 하단탭이 있는 화면이 먼저 나오게 해 준다.
3) Bottom Tab Navigator에 navigation을 인자로 전달한다.
이전 포스팅 예제에서 TabNavi의 인자로 navigation을 전달해준다. 이 navigation은 위에서 만들어준 Stack Navigator의 navigation prop이다.
const TabNavi = ({ navigation }) => {
4) 이전 포스팅 예제에서, "카테고리" 탭에 해당하는 Tab.Screen을 아래처럼 수정해준다.
...(생략)...
<Tab.Screen
name="Category"
component={TabPlaceholder}
options={{
tabBarLabel: "카테고리",
tabBarIcon: () => (
<CategoryIcon width={widthPercentage(24)} height={heightPercentage(24)} />
),
}}
listeners={() => ({
tabPress: (e) => {
e.preventDefault();
navigation.navigate("NewScreen");
},
})}
/>
...(생략)...
React Navigation에서 Screen에 대한 prop으로 listeners를 사용할 수 있다. (공식 문서)
listeners는 key값으로 이벤트 이름을, value값으로 listener callback을 정의해준다.
위의 예제에선 탭을 눌렀을 때 일어나는 이벤트인 tabPress를 key값으로 정의해주었다.
callback함수 내용으론,
- e.preventDefault() : default action을 막음
- navigation.navigate("NewScreen"): "NewScreen"이란 이름을 가진 Screen으로 이동
여기서 navigation은 3) 번에서 인자로 전달해준 것이다!
4. 마무리
자, 위의 코드들이 제대로 적용이 완료됐다면
아래 화면처럼 "카테고리" 탭을 눌렀을 때 새로운 화면에 잘 나오는 것을 확인할 수 있다!
> 전체 코드 보기
예제를 테스트하기 전 확인 사항
- "./Config/ResponsiveSize": 화면 크기에 따른 component size 비율 조정 함수 정의 ([React Native] 10. 반응형 디자인 적용하기 참고)
- Tab.Screen에 사용된 icon들은 수정해서 사용 (아래 예제에서 사용한 icon은 첨부하지 않겠습니다)
- font 설정 필요 (or 지우고 테스트)
import React from "react";
import { Dimensions, StatusBar } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createStackNavigator, StackNavigationProp } from "@react-navigation/stack";
import { widthPercentage, heightPercentage, fontPercentage } from "./Config/ResponsiveSize";
import { NavigationContainer } from "@react-navigation/native";
import Styled from "styled-components/native";
const ScreenHeight = Dimensions.get("window").height;
let StatusHeight = StatusBar.currentHeight;
if (!StatusHeight) {
StatusHeight = 0;
}
const Placeholder = Styled.View`
width: ${widthPercentage(360)}px;
height: ${ScreenHeight + StatusHeight}px;
paddingLeft: ${widthPercentage(155)}px;
paddingTop: ${heightPercentage(360)}px;
background-color: #FFFF11;
`;
const Tab = createBottomTabNavigator();
const TabPlaceholder = () => {
return (
<Placeholder>
<Text>example</Text>
</Placeholder>
);
};
const NewScreen = () => {
return (
<Placeholder style={{ backgroundColor: "#FF1111" }}>
<Text>New Screen</Text>
</Placeholder>
);
};
const TabNavi = ({ navigation }) => {
return (
<Tab.Navigator
tabBarOptions={{
activeTintColor: "#7DD421",
inactiveTintColor: "#222222",
style: {
height: heightPercentage(56),
borderTopWidth: heightPercentage(0.5),
borderTopColor: "#E9E9E9",
backgroundColor: "#FFFFFF",
},
iconStyle: {
marginTop: heightPercentage(10),
},
labelStyle: {
fontFamily: "NotoSansKR-Regular",
fontSize: fontPercentage(10),
},
}}
>
<Tab.Screen
name="Home"
component={TabPlaceholder}
options={{
tabBarLabel: "홈",
tabBarIcon: ({ focused }) =>
focused ? (
<ActiveHomeIcon width={widthPercentage(24)} height={heightPercentage(24)} />
) : (
<InactiveHomeIcon width={widthPercentage(24)} height={heightPercentage(24)} />
),
}}
/>
<Tab.Screen
name="Category"
component={TabPlaceholder}
options={{
tabBarLabel: "카테고리",
tabBarIcon: () => (
<CategoryIcon width={widthPercentage(24)} height={heightPercentage(24)} />
),
}}
listeners={() => ({
tabPress: (e) => {
e.preventDefault();
navigation.navigate("NewScreen");
},
})}
/>
<Tab.Screen
name="Chatting"
component={TabPlaceholder}
options={{
tabBarLabel: "채팅",
tabBarIcon: ({ focused }) =>
focused ? (
<ActiveChatIcon width={widthPercentage(24)} height={heightPercentage(24)} />
) : (
<InactiveChatIcon width={widthPercentage(24)} height={heightPercentage(24)} />
),
}}
/>
<Tab.Screen
name="Profile"
component={TabPlaceholder}
options={{
tabBarLabel: "프로필",
tabBarIcon: ({ focused }) =>
focused ? (
<ActiveProfileIcon width={widthPercentage(24)} height={heightPercentage(24)} />
) : (
<InactiveProfileIcon width={widthPercentage(24)} height={heightPercentage(24)} />
),
}}
/>
</Tab.Navigator>
);
};
const Stack = createStackNavigator();
const WholeStack = () => {
return (
<Stack.Navigator initialRouteName="TabNavi">
<Stack.Screen
name="TabNavi"
component={TabNavi}
options={{ headerShown: false, animationEnabled: false }}
/>
<Stack.Screen
name="NewScreen"
component={NewScreen}
options={{ headerShown: false, animationEnabled: false }}
/>
</Stack.Navigator>
);
};
export default () => {
return (
<NavigationContainer>
<WholeStack />
</NavigationContainer>
);
};
'CS > React-Native' 카테고리의 다른 글
[React Native] 10. 반응형 디자인 적용하기 (2) | 2021.09.02 |
---|---|
[React-Native] 8. Bottom Tab Navigator 사용하기 (0) | 2021.08.31 |
[React-Native] 7. StatusBar 사용하기 (앱 상태바 조작) (0) | 2021.03.17 |
[React-Native] 6. react-native-make로 앱아이콘 만들기 (0) | 2021.03.17 |
[React-Native] 5. Splash Screen 만들기 (0) | 2021.03.17 |
- Total
- Today
- Yesterday
- BFS
- C++
- react-native
- react-native-make
- application
- error
- problem
- 삼성sw역량테스트
- algorithm
- 뉴욕여행
- 삼성SW역량테스트 기출
- Problem Solving
- beakjoon
- 시뮬레이션
- 일기
- typescript
- 웨이팅후기
- react native
- 백준
- 구현
- 기출
- 지킬앤하이드
- DFS
- 하단탭
- DP
- 브루트포스 알고리즘
- rn
- Android
- 알고리즘
- react navigation
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |