Stack + Drawer + Tab + MaterialTab + MaterialTopTab 사용하기
DrawerNavi
ㄴ HomeStack
ㄴ HomeScreen
ㄴ DetailScreen
ㄴ ProfileStack
ㄴ ProfileScreen
ㄴ NotificationScreen
ㄴ TabNavi
ㄴTabFirstStackNavi
ㄴTabFirst
ㄴModal
ㄴTabSecond
ㄴ MatertialTabStackNavi
ㄴTabFirstStackNavi
ㄴTabFirst
ㄴModal
ㄴTabSecond
ㄴ MaterialTopTabStackNavi
ㄴTabFirstStackNavi
ㄴTabFirst
ㄴModal
ㄴTabSecond
*공부용으로 모든 네비게이터를 사용했음
Home에서 Detail스크린으로 이동하는 HomeStack과 Profile에서 Notification 스크린으로 이동하는 ProfileStack 두개로 나눠서 스택 네비게이터를 만들었다.
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './HomeScreen';
import ProfileScreen from './ProfileScreen';
const Stack = createNativeStackNavigator();
const HomeStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={({navigation}) => ({
// headerShown: false,
title: 'Home',
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Text>Drawer</Text>
</TouchableOpacity>
),
})}
/>
<Stack.Screen
name="Detail"
component={Detail}
options={{title: 'Detail'}}
/>
</Stack.Navigator>
);
};
const ProfileStack = ({navigation}) => {
return (
<Stack.Navigator>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={{
title: 'Profile',
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Text>Drawer</Text>
</TouchableOpacity>
),
}}
/>
<Stack.Screen
name="Notification"
component={Notification}
options={{title: 'Notification'}}
/>
</Stack.Navigator>
);
};
// 📌 onPress={() => navigation.openDrawer()는 drawer 네이게이터를 만들 때 다룰 것이다.
첫번째 탭에서는 모달을 사용하기 때문에 따로 TabFisrtStackNavi로 분리해 컴포넌트를 생성하고 탭 네비게이터에 넣었다.
TabFirstStackNavi
ㄴTabFirst
ㄴModal
TabNavi
ㄴTabFirstStack
ㄴTabSecond
const Tab = createBottomTabNavigator();
const TabFirstStackNavi = ({navigation}) => {
return (
<Stack.Navigator>
<Stack.Screen
name="Tab First"
component={TabFisrt}
options={{headerShown: false}}
/>
<Stack.Screen
name="Modal"
component={Modal}
options={{
presentation: 'modal',
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text>닫기</Text>
</TouchableOpacity>
),
}}
/>
</Stack.Navigator>
);
};
const TabNavi = () => {
return (
<Tab.Navigator
initialRouteName="Home"
screenOptions={{
tabBarActiveTintColor: '#e91e63',
tabBarLabelStyle: {fontSize: 12},
tabBarStyle: {backgroundColor: 'powderblue'},
}}>
<Tab.Screen
name="Home"
component={TabFirstStackNavi}
options={{tabBarLabel: 'Home'}}
/>
<Tab.Screen
name="Second"
component={TabSecond}
options={{tabBarLabel: 'Second'}}
/>
</Tab.Navigator>
);
};
Matertial Tab은 기본 Tab에서 애니메이션 효과를 추가한 네이게이터이다. 커스텀해서 사용할수도 있고 디폴트로 애니메이션 효과도 내장되어 있다.
// Matertial bottom tab (tab with animation)
const MatertialTab = createMaterialBottomTabNavigator();
const MatertialTabNavi = () => {
return (
<MatertialTab.Navigator initialRouteName="First">
<MatertialTab.Screen name="First" component={TabFirstStackNavi} />
<MatertialTab.Screen name="Second" component={TabSecond} />
</MatertialTab.Navigator>
);
};
const MaterialTobTab = createMaterialTopTabNavigator();
const MaterialTopTabNavi = () => {
return (
<MaterialTobTab.Navigator>
<MaterialTobTab.Screen
name="Home"
component={TabFirstStackNavi}
options={{headerShown: false}}
/>
<MaterialTobTab.Screen
name="Second"
component={TabSecond}
options={{headerShown: false}}
/>
</MaterialTobTab.Navigator>
);
};
// 📌 material tab 네이게이션은 헤더를 지원하지 않는다. -> 헤더를 사용하려면 stack navigator로 감싸줘야한다.
// 📌 matertial top navigation에 헤더를 넣어주기 위해 stack에 넣어준다.
// 위 캡쳐샷과 같이 MaterialTopTabNavi라는 헤더가 생성된다.
const MaterialTopTabStackNavi = ({navigation}) => {
return (
<Stack.Navigator
screenOptions={{
headerLeft: props => (
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Text>Drawer</Text>
</TouchableOpacity>
),
}}>
<Stack.Screen name="MaterialTopTabNavi" component={MaterialTopTabNavi} />
</Stack.Navigator>
);
};
드로어를 전역에서 사용하기 위해서 default로 export 한다.
커스텀해서 사용하고 싶다면 커스텀 드로어 컴포넌트를 만들고 드로어 네비게이터에 props전달해서 커스텀 컴포넌트를 리턴하면 된다.
const DrawerNavi = ({navigation}) => {
return (
<Drawer.Navigator
initialRouteName="Notes"
// drawerContent={props => <CustomDrawerContent {...props} />}
screenOptions={{
headerShown: false,
drawerActiveTintColor: 'red',
drawerActiveBackgroundColor: 'steelblue',
drawerInactiveTintColor: 'black',
}}>
<Drawer.Screen
name="Notes"
component={HomeStack}
options={{
drawerLabel: 'HOME',
}}
/>
<Drawer.Screen
name="User"
component={ProfileStack}
options={{drawerLabel: 'PROFILE'}}
/>
<Drawer.Screen name="TabNavi" component={TabNavi} />
<Drawer.Screen
name="MatertialTabStackNavi"
component={MatertialTabStackNavi}
/>
{/* <Drawer.Screen name="MaterialTopTabNavi" component={MaterialTopTabNavi} /> */}
<Drawer.Screen
name="MaterialTopTabStackNavi"
component={MaterialTopTabStackNavi}
/>
</Drawer.Navigator>
);
};
// 커스텀 드로어
const CustomDrawerContent = props => {
return (
<DrawerContentScrollView {...props} style={{backgroundColor: 'gold'}}>
<DrawerItemList {...props} />
<DrawerItem
label="Home"
inactiveBackgroundColor="gold"
activeBackgroundColor="steelblue"
activeTintColor="white"
onPress={() => props.navigation.navigate('Home')}
/>
<DrawerItem
label="Profile"
onPress={() => props.navigation.navigate('User', {screen: 'Profile'})}
/>
</DrawerContentScrollView>
);
};
export default DrawerNavi;
function App() {
return (
<NavigationContainer>
<DrawerNavi />
</NavigationContainer>
);
}
export default App;