[React Native] React Navigation - 7. [Stack] Header Bar 커스터마이징

2022. 1. 17. 00:56React Native/Basic

 

 


 


 


7. [Stack] Header Bar 커스터마이징

헤더바에 로고를 넣는 방법을 알아보자. src 폴더 내에 assets/pics 라는 이름으로 로고 아이콘을 저장할 폴더를 만든다. 그리고 로고 아이콘 이미지 파일을 해당 폴더 내에 저장한다. 그럼 준비는 끝난다.

 

이미지를 가져오는 것이기 때문에 App.js 에 Image를 추가로 import 해준다.

import {StyleSheet, Text, View, Image} from 'react-native';
  logoTitle = () => {
    return (
      <Image
        style={{width: 40, height: 40}}
        source={require('./src/assets/pics/home_icon.png')}
      />
    );
  };

logoTitle 이라는 이름의 함수를 만들었다. 여기서는 Image 태그를 사용하여 아이콘 이미지를 가져온다. style 로 크기를 지정해 준 뒤, source 에 파일 경로를 작성한다. inline으로 작성할 때는 require를 사용해 주면 된다.

<Stack.Screen
    name="Home"
    component={HomeScreen}
    options={{
      title: 'Home Screen',
      headerTitle: () => <this.logoTitle />,
      // headerTitle: () => <LogoTitle />,

      // headerTitle: <this.logoTitle />, // 버전이 업데이트되면서 달라졌는지 해당 코드 적용 안 됨.
    }}
/>

그리고 스크린의 옵션에서 herderTitle로 위에서 작성한 logoTitle 태그를 작성한다.

 

+) 강의 상에서는 headerTitle: <this.logoTitle /> 로 동작했지만 버전이 업데이트 되고 나서 변경된 사항인지 아이콘이 들어가지 않았다. 위와 같이 headerTitle: () => <this.logoTitle /> 로 해야 동작했다.

그리고 강의 상에서는 headerBackTitle 또한 자연스레 로고 아이콘으로 바뀌었지만 현재 코드를 입력할 때는 headerBackTitle 이 이미지로 바뀌지 않았다.

 

headerBackTitle을 다른 글자로 바꾸려면 setOptions 에서 headerBackTitle를 설정해주면 된다.

/* ...
코드 생략 
...
*/
headerStyle = () => {
    this.props.navigation.setOptions({
      title: 'Customizing',
      headerStyle: {
        backgroundColor: 'blue',
      },
      headerTintColor: 'yellow',
      headerTitleStyle: {
        fontWeight: 'bold',
        color: 'green',
      },
      headerBackTitle: 'BACK',
    });
  };

  render() {
    this.headerStyle();
    
/* ...
코드 생략 
...
*/

 

logo.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {StyleSheet, Image} from 'react-native';

import Logo from './assets/pics/home_icon.png';

class LogoTitle extends Component {
  render() {
    return <Image style={{width: 40, height: 40}} source={Logo} />;
  }
}

const styles = StyleSheet.create({});

export default LogoTitle;

user.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {StyleSheet, Text, View, Button} from 'react-native';

import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

class UserScreen extends Component {
  headerStyle = () => {
    this.props.navigation.setOptions({
      title: 'Customizing',
      headerStyle: {
        backgroundColor: 'blue',
      },
      headerTintColor: 'yellow',
      headerTitleStyle: {
        fontWeight: 'bold',
        color: 'green',
      },
      headerBackTitle: 'BACK',
    });
  };

  render() {
    this.headerStyle();
    const {params} = this.props.route;
    const userIdx = params ? params.userIdx : null;
    const userName = params ? params.userName : null;
    const userLastName = params ? params.userLastName : null;

    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          justifyContent: 'center',
        }}>
        <Text>User Screen</Text>
        <Button
          title="To Home Screen"
          onPress={() => {
            this.props.navigation.navigate('Home');
          }}
        />
        <Text>User Idx : {JSON.stringify(userIdx)}</Text>
        <Text>User Name : {JSON.stringify(userName)}</Text>
        <Text>User LastName : {JSON.stringify(userLastName)}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({});

export default UserScreen;

home.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {StyleSheet, Text, View, Button} from 'react-native';

import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

class HomeScreen extends Component {
  render() {
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          justifyContent: 'center',
        }}>
        <Text>Home Screen</Text>
        <Button
          title="To User Screen"
          onPress={() => {
            this.props.navigation.navigate('User', {
              userIdx: 100,
              userName: 'Gildong',
              userLastName: 'Hong',
            });
          }}
        />
        <Button
          title="Change the title"
          onPress={() => {
            this.props.navigation.setOptions({
              title: 'Changed!!!',
              headerStyle: {
                backgroundColor: 'pink',
              },
              headerTintColor: 'red',
            });
          }}></Button>
      </View>
    );
  }
}

const styles = StyleSheet.create({});

export default HomeScreen;

App.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {StyleSheet, Text, View, Image} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './src/home';
import UserScreen from './src/user';
import LogoTitle from './src/logo';

const Stack = createNativeStackNavigator();

class App extends Component {
  logoTitle = () => {
    return (
      <Image
        style={{width: 40, height: 40}}
        source={require('./src/assets/pics/home_icon.png')}
      />
    );
  };

  render() {
    return (
      <NavigationContainer>
        <Stack.Navigator
          initialRouteName="Home"
          screenOptions={{
            headerStyle: {
              backgroundColor: '#a4511e',
            },
            headerTintColor: '#ffffff',
            headerTitleStyle: {
              fontWeight: 'bold',
              color: '#f3d612',
            },
          }}>
          <Stack.Screen
            name="Home"
            component={HomeScreen}
            options={{
              title: 'Home Screen',
              headerTitle: () => <LogoTitle />,
            }}
          />
          <Stack.Screen
            name="User"
            component={UserScreen}
            initialParams={{
              userIdx: 50,
              userName: 'Gildong',
              userLastName: 'Go',
            }}
            options={{
              title: 'User Screen',
              headerStyle: {
                backgroundColor: 'pink',
              },
              headerTintColor: 'red',
              headerTitleStyle: {
                fontWeight: 'bold',
                color: 'purple',
              },
            }}
          />
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}

const styles = StyleSheet.create({});

export default App;

참고 자료

https://www.inflearn.com/course/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-%EA%B8%B0%EC%B4%88/dashboard

 

iOS/Android 앱 개발을 위한 실전 React Native - Basic - 인프런 | 강의

Mobile App Front-End 개발을 위한 React Native의 기초 지식 습득을 목표로 하고 있습니다. 진입장벽이 낮은 언어/API의 활용을 통해 비전문가도 쉽게 Native Mobile App을 개발할 수 있도록 제작된 강의입니다

www.inflearn.com