본문으로 이동

플러터:화면 전환(화면 쌓기, 하단 네비게이션 바): 두 판 사이의 차이

학교의 모든 지식. SMwiki
 
(차이 없음)

2026년 1월 7일 (수) 01:50 기준 최신판

틀:플러터 Dart:개요 플러터에 대한 지식 분류

  1. 플러터:개요
    1. 플러터:VSCode
    2. 플러터:안드로이드 스튜디오
  2. 플러터:실행
  3. 플러터:개념 잡기
    1. 플러터:화면 하나 만들기
    2. 플러터:변하는 화면(StatefulWidget)
    3. 플러터:화면 전환(화면 쌓기, 하단 네비게이션 바)
    4. 플러터:화면 전환(Drawer)
    5. 플러터:입력 관련
      1. 플러터:버튼
      2. 플러터:키보드 입력
      3. 플러터:슬라이더
    6. 플러터:그래프 그리기(fl chart)
    7. 플러터:데이터 저장(간단한 데이터)
    8. 플러터:인증(Firebase 인증)(미완)
    9. 플러터:인증(OAuth2)(미완)
  4. 권한 사용
    1. 플러터:마이크 입력
  5. 위젯
    1. 플러터:아이콘
    2. 플러터:레이아웃 계열 위젯
    3. 플러터:네비게이션 계열 위젯
    4. 플러터:버튼
    5. 플러터:상태관리(미완)
  6. 플러터:DB연결
    1. 플러터:Firebase(미완)
    2. 플러터:MySQL(미완)
  7. 디자인
    1. 플러터:테마
    2. 플러터:앱바
  8. 플러터:배포
  9. 플러터:참고자료
  10. 플러터:위젯
    1. 플러터:공간배치용 위젯
  11. 플러터:라이브러리
    1. 플러터:logger

네이게이션을 통한 화면전환.

기본적으로 네비게이션바로 구조를 잡고, 네비게이터로 상세 화면을 다루는 형식을 많이 쓴다.

기본 화면 전환(Navigator)

[편집 | 원본 편집]
  • Flutter 앱에서 화면을 이동하는 가장 기본적인 방식은 Navigator를 사용하는 것이다.
  • Navigator는 “화면(stack)”을 관리하며, 새로운 페이지를 push하여 화면을 열고 pop하여 닫는다.
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Navigator Demo',
      debugShowCheckedModeBanner: false,
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget {
  // StatelessWidget: 상태(state)를 가지지 않는 화면
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("첫 번째 화면"),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text("두 번째 화면으로 이동"),
          onPressed: () {
            // 화면 이동 (push)
            Navigator.push(
              context,  // 현재 위젯의 위치가 어디인지.(어디 위에 화면을 올릴 것인지.)
              MaterialPageRoute(builder: (_) => SecondPage()),
            );
          },
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  // 두 번째 화면도 상태를 가지지 않는 StatelessWidget
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("두 번째 화면"),
      ),
      body: Center(
        child: Text(
          "여기는 두 번째 화면!",
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

이해를 위한 추가 설명

[편집 | 원본 편집]
요소 설명 비고
화면을 위에 올리기.

Navigator.push

Navigator.push(
context,
MaterialPageRoute(builder: (_) => SecondPage()),
);

새로운 페이지를 스택 위에 ‘올려서’ 이동한다.

MaterialPageRoute는 기본적인 화면 전환 애니메이션을 제공한다.

마테리얼 디자인 규칙에 따라 뒤로가기가 가능하면 자동으로 뒤로가기 버튼이 생긴다.

_는 '인자를 받긴 해야 하지만, 나는 쓰지 않겠다'라는 의미의 Dart 관례적인 이름.(원랜 BuildContext context가 들어감.)

뒤로 가기

Navigator.pop

Navigator.pop(context)

현재 페이지를 스택에서 제거(pop)하여 이전 화면으로 돌아간다.

위 코드엔 없지만, 특정 함수에서 진행하면 창이 닫힌다.

스택을 쌓아 화면이 바뀐다.

왜 push()는 context가 필요한가?

[편집 | 원본 편집]

Navigator는 위젯 트리 안에 존재하는 “Navigator State”를 찾아야 하는데, 이를 위해 현재 위젯의 BuildContext가 필요하다.

BuildContext는 “현재 위젯이 트리에서 어디 위치하는지”를 나타내는 정보다.

MaterialPageRoute 말고 다른 것도 있나?

[편집 | 원본 편집]

있다.

  • CupertinoPageRoute (iOS 스타일 전환)
  • PageRouteBuilder (전환 애니메이션 직접 커스텀)
  • go_router, auto_route 같은 라우팅 라이브러리

기본 하단 네비게이션 바

[편집 | 원본 편집]
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BottomNavigation Demo',
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0; // 현재 선택된 탭

  // 탭마다 보여줄 화면
  static const List<Widget> _pages = <Widget>[  // static은 클래스 변수임을 의미미(인스턴스가 생길 때마다 새로 만들지는 않겠다.)
    Center(
      child: Text(
        '첫 번째 화면',
        style: TextStyle(fontSize: 24),
      ),
    ),
    Center(
      child: Text(
        '두 번째 화면',
        style: TextStyle(fontSize: 24),
      ),
    ),
    Center(
      child: Text(
        '세 번째 화면',
        style: TextStyle(fontSize: 24),
      ),
    ),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index; // 탭 선택 시 상태 변경
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('BottomNavigationBar Demo'),
      ),
      body: _pages[_selectedIndex], // 현재 선택된 화면 표시
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: _onItemTapped, // 탭 클릭 시 호출
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: '홈',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: '비즈니스',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: '학교',
          ),
        ],
      ),
    );
  }
}

이해를 위한 추가 설명

[편집 | 원본 편집]
요소 설명 비고
_onItemTapped 탭 클릭 시 호출되는 함수.

자동으로 Index가 입력된다.

BottomNavigationBarType 옵션은?
  • fixed: 모든 탭이 항상 같은 너비로 표시
  • shifting: 선택된 탭 강조, 배경색 변화 가능

기본값은 탭이 4개 이하면 fixed, 4개 이상이면 shifting

기본값은 아래 옵션으로 바꾸어 지정 가능.

  type: BottomNavigationBarType.fixed, // 고정형

shifting이면 각 탭에 색을 넣어주어야 한다.

backgroundColor: Colors.blue, 형태로.

StatelessWidget으로도 만들 수 없나?

[편집 | 원본 편집]

탭 선택 상태를 저장할 방법이 없으므로 일반 StatelessWidget으로는 불가능하다. 탭 상태를 유지하면서 화면 전환하려면 StatefulWidget을 사용해야 한다.