LifeSports Application(ReactNative & Nest.js) - 4. BottomNavigation
41413 ワード
#1 BottomNavigation
BottomNavigationは、ユーザーがボタンをクリックしたときにボタンを下に置き、必要な画面にジャンプできるナビゲーション機能です.
上のフラッシュメモリ画像はデータムナビゲーションです.
#2 BottomNavigation実施
私はBottomNavigationをホームページに置くので、HomeScreenではなくLoginscreenとRegisterScreenがいるStackNavigationにBottomNavigationを置きます.
以下のコマンドを使用してパッケージをインストールします.アイコンパッケージもインストールします.
npm install --save @react-navigation/bottom-tabs
npm install --save react-native-vector-icons/Ionicons
そしてBottomNavigatorディレクトリにBottomNavigationがナビゲーションを実現するためにjsを作成します.import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import palette from '../styles/palette';
import HomeScreen from '../pages/home/HomeScreen';
import PostScreen from '../pages/post/PostScreen';
import MapScreen from '../pages/map/MapScreen';
import MyPageScreen from '../pages/user/MyPageScreen';
const Tab = createBottomTabNavigator();
const BottomNavigation = ({ route }) => {
return(
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color }) => {
var iconName;
var iconSize;
if(route.name === "Home") {
iconName = focused ? 'ios-home' : 'ios-home-outline';
iconSize = focused ? 32 : 24;
} else if (route.name === 'Board') {
iconName = focused ? 'ios-reader' : 'ios-reader-outline';
iconSize = focused ? 32 : 24;
} else if (route.name === 'Map'){
iconName = focused ? 'ios-location' : 'ios-location-outline';
iconSize = focused ? 32 : 24;
} else if (route.name === 'Setting'){
iconName = focused ? 'ios-person' : 'ios-person-outline';
iconSize = focused ? 32 : 24;
}
return (
<Icon
size={ iconSize }
name={ iconName }
color={ color }
/>
)
}
})}
tabBarOptions = {{
activeTintColor: palette.blue[4],
inactiveTintColor: palette.gray[5],
}}
>
<Tab.Screen
name="Home"
children={
() => <HomeScreen />
}
/>
<Tab.Screen
name="Post"
children={
() => <PostScreen />
}
/>
<Tab.Screen
name="Map"
children={
() => <MapScreen />
}
/>
<Tab.Screen
name="MyPage"
children={
() => <MyPageScreen />
}
/>
</Tab.Navigator>
);
};
export default BottomNavigation;
import React from 'react';
import 'react-native-gesture-handler';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
import LoginScreen from '../pages/auth/LoginScreen';
import RegisterScreen from '../pages/auth/RegisterScreen';
import BottomNavigation from './BottomNavigation';
const Stack = createStackNavigator();
const StackNavigatior = () => {
return(
<NavigationContainer>
<Stack.Navigator>
...
<Stack.Screen
name="Tab"
component={ BottomNavigation }
options={{
headerShown: false
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default StackNavigatior;
import React from 'react';
import { View, StyleSheet } from 'react-native';
import StyledBorderButton from '../../../styles/common/StyledBorderButton';
import StyledFullButton from '../../../styles/common/StyledFullButton';
import StyledTextInput from '../../../styles/common/StyledTextInput';
import palette from '../../../styles/palette';
const LoginForm = ({ navigation }) => {
...
const onPressMainNavigator = e => {
e.preventDefault();
navigation.navigate('Tab');
};
return(
<View style={ styles.loginBox }>
...
<StyledFullButton
onPress={ onPressMainNavigator }
text="Sign in"
/>
...
</View>
);
};
...
export default LoginForm;
https://unchae.tistory.com/entry/RN-react-native-vector-icons-%EC%97%91%EB%B0%95%EC%9C%BC%EB%A1%9C-%EB%9C%B0-%EA%B2%BD%EC%9A%B0
アイコンとデータムナビゲーション機能は正常です.
それではHomeScreenの画面を実現しましょうHomeScreenは、プロジェクトごとにカテゴリを作成する機能を提供しており、プロジェクトアイコンをクリックすると、それに関連する運動場所を地図に表示できます.
import React from 'react';
import {
StyleSheet,
View
} from 'react-native';
import CategoryIcon from '../../../styles/common/CategoryIcon';
import ImageIcon from '../../../styles/common/ImageIcon';
import palette from '../../../styles/palette';
const HomeContent = () => {
return(
<View style={ styles.container }>
<View style={ styles.categoryLine }>
<CategoryIcon
name={ "ios-baseball-outline" }
text={ "야구" }
type_nm={ "야구장" }
/>
<CategoryIcon
name={ "ios-basketball-outline" }
text={ "농구" }
type_nm={ "생활체육관" }
/>
<CategoryIcon
name={ "ios-basketball" }
text={ "야외농구" }
type_nm={ "농구장" }
/>
<CategoryIcon
name={ "ios-football-outline" }
text={ "축구" }
type_nm={ "축구장" }
/>
</View>
<View style={ styles.categoryLine }>
<ImageIcon
name={ "arrow" }
text={ "양궁" }
type_nm={ "국궁장" }
/>
<ImageIcon
name={ "badminton" }
text={ "배드민턴" }
type_nm={ "배드민턴장" }
/>
<ImageIcon
name={ "climb" }
text={ "클라이밍" }
type_nm={ "클라이밍장" }
/>
<ImageIcon
name={ "gateball" }
text={ "게이트볼" }
type_nm={ "게이트볼장" }
/>
</View>
<View style={ styles.categoryLine }>
<ImageIcon
name={ "ice_skate" }
text={ "스케이트" }
type_nm={ "빙상장" }
/>
<ImageIcon
name={ "inline_skate" }
text={ "인라인" }
type={ "인라인스케이트장" }
/>
<ImageIcon
name={ "pingpong" }
text={ "탁구" }
type_nm={ "탁구장" }
/>
<ImageIcon
name={ "sepak_takraw" }
text={ "족구" }
type_nm={ "족구장" }
/>
</View>
<View style={ styles.categoryLine }>
<ImageIcon
name={ "shoot" }
text={ "사격" }
type_nm={ "사격장" }
/>
<ImageIcon
name={ "swim" }
text={ "수영" }
type_nm={ "수영장" }
/>
<ImageIcon
name={ "volleyball" }
text={ "배구" }
type_nm={ "구기체육관" }
/>
<ImageIcon
name={ "volleyball" }
text={ "야외배구" }
type_nm={ "배구장" }
/>
</View>
<View style={ styles.categoryLine }>
<CategoryIcon
name={ "ios-bicycle" }
text={ "자전거" }
type_nm={ "산악자전거장" }
/>
<CategoryIcon
name={ "ios-school" }
text={ "학교체육" }
type_nm={ "학교체육시설" }
/>
<CategoryIcon
name={ "ios-football" }
text={ "풋살" }
type_nm={ "풋살장" }
/>
<ImageIcon
name={ "tennis" }
text={ "테니스" }
type_nm={ "테니스장" }
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
marginTop: 30,
width: 420,
backgroundColor: palette.white[0],
},
containerTitle: {
alignItems: 'center',
justifyContent: 'center',
},
textTitle: {
fontWeight: 'bold',
fontSize: 20,
},
categoryLine: {
flexDirection: 'row',
width: 420,
height: 70,
marginBottom: 20,
},
});
export default HomeContent;
カテゴリアイコンを含む構成部品.iKONを作ろうimport React from 'react';
import {
StyleSheet,
View,
Text,
TouchableOpacity
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import palette from '../palette';
const CategoryIcon = ({
name,
text
}) => {
return(
<View style={ styles.container }>
<TouchableOpacity>
<Icon
size={ 48 }
name={ name }
color={ palette.blue[4] }
/>
</TouchableOpacity>
<Text style={ styles.font }>
{ text }
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
width: 60,
height: 60,
margin: 20,
},
font: {
fontWeight: 'bold',
},
});
export default CategoryIcon;
import React from 'react';
import {
StyleSheet,
View,
TouchableOpacity,
Image,
Text
} from 'react-native';
import palette from '../palette';
import arrow from '../../assets/img/arrow.png';
import badminton from '../../assets/img/badminton.png';
import climb from '../../assets/img/climb.png';
import gateball from '../../assets/img/gateball.png';
import ice_skate from '../../assets/img/ice_skate.png';
import inline_skate from '../../assets/img/inline_skate.png';
import pingpong from '../../assets/img/pingpong.png';
import sepak_takraw from '../../assets/img/sepak_takraw.png';
import shoot from '../../assets/img/shoot.png';
import swim from '../../assets/img/swim.png';
import volleyball from '../../assets/img/volleyball.png';
import tennis from '../../assets/img/tennis.png';
const ImageIcon = ({ name, text }) => {
if(name === "arrow") name = arrow
else if(name === "badminton") name = badminton
else if(name === "climb") name = climb
else if(name === "gateball") name = gateball
else if(name === "ice_skate") name = ice_skate
else if(name === "inline_skate") name = inline_skate
else if(name === "pingpong") name = pingpong
else if(name === "sepak_takraw") name = sepak_takraw
else if(name === "shoot") name = shoot
else if(name === "swim") name = swim
else if(name === "volleyball") name = volleyball
else if(name === 'tennis') name = tennis;
return(
<View style={ styles.container }>
<TouchableOpacity>
<Image
style={ styles.icon }
source={ name }
/>
</TouchableOpacity>
<Text style={ styles.font }>
{ text }
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
width: 60,
height: 60,
margin: 20,
},
icon: {
tintColor: palette.blue[4],
},
font: {
fontWeight: 'bold',
},
});
export default ImageIcon;
ImageIconは、自分でダウンロードして作成したイメージファイルです.画像とフォントに関するファイルを襟に置きます.https://github.com/biuea3866/MyLifeSports
次に、HomeScreenのタイトルセクションを変更します.
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import palette from '../styles/palette';
import HomeScreen from '../pages/home/HomeScreen';
import PostScreen from '../pages/post/PostScreen';
import MapScreen from '../pages/map/MapScreen';
import MyPageScreen from '../pages/user/MyPageScreen';
const Tab = createBottomTabNavigator();
const BottomNavigation = ({ route }) => {
return(
...
<Tab.Screen
name="Home"
options={{
title: 'Life Sport',
tabBarLabel: 'Home',
headerStyle: {
backgroundColor: palette.blue[4],
},
headerTintColor: palette.white[0],
headerTitleStyle: {
fontWeight: 'bold'
},
}}
children={
() => <HomeScreen />
}
/>
...
};
export default BottomNavigation;
結果画面.よく撮れている様子が見られますこのようにして、投稿ページ、地図ページ、および私のページを作成します.
Reference
この問題について(LifeSports Application(ReactNative & Nest.js) - 4. BottomNavigation), 我々は、より多くの情報をここで見つけました https://velog.io/@biuea/LifeSports-ApplicationReactNative-Node.js-4.-BottomNavigationテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol