728x90
반응형
Flutter에서 상단 바, 하단 네비게이션 구현하기
main.dart
MainPage 위젯을 통해 구성된 애플리케이션이다. 애플리케이션의 전체적인 테마와 페이지 구성을 설정하고, 페이지 간 이동을 관리한다.
- MyApp: MaterialApp을 생성하여 애플리케이션 전체의 테마와 기본 설정을 지정. title은 애플리케이션의 제목을 설정하고, theme은 전체적인 테마 설정을 담고 있음.
- MainPage: StatefulWidget를 상속하여 페이지 이동과 BottomNavigationBar를 관리하는 위젯
_currentIndex 변수를 사용하여 현재 선택된 페이지 인덱스를 관리하며, _onItemTapped 함수는 탭 이벤트를 처리하여 _currentIndex를 업데이트
_pages 리스트에는 홈페이지와 세 개의 탭 페이지 위젯이 포함 - build: Scaffold를 구성하여 앱의 기본 레이아웃을 정의
- AppBar는 뒤로가기 버튼을 추가한 상단 앱 바를 표시
- body는 현재 선택된 페이지에 해당하는 위젯을 표시
- bottomNavigationBar는 네비게이션 바로, 사용자가 선택한 탭에 따라 현재 페이지를 업데이트
HomePage, Tab1Page, Tab2Page, Tab3Page라는 각각의 페이지 위젯을 생성하고 _pages 리스트에 추가하여 페이지 간 이동을 처리.
BottomNavigationBar를 통해 사용자가 원하는 페이지로 이동할 수 있다.
import 'package:flutter/material.dart';
import 'package:musicalapp/home.dart';
import 'package:musicalapp/tab1.dart';
import 'package:musicalapp/tab2.dart';
import 'package:musicalapp/tab3.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Mobile App',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: AppBarTheme(
backgroundColor: Colors.white, // 기본 색상
)),
home: MainPage(),
);
}
}
class MainPage extends StatefulWidget {
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int _currentIndex = 0;
final List<Widget> _pages = [HomePage(), Tab1Page(), Tab2Page(), Tab3Page()];
void _onItemTapped(int index) {
setState(() {
_currentIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//title: Text('My Mobile App'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
color: Colors.grey,
onPressed: () {
// 뒤로가기 버튼 동작
},
),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '홈',
),
BottomNavigationBarItem(
icon: Icon(Icons.event),
label: '탭1',
),
BottomNavigationBarItem(
icon: Icon(Icons.tiktok),
label: '탭2',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'MY',
),
],
currentIndex: _currentIndex,
selectedItemColor: Color.fromARGB(255, 197, 142, 233),
unselectedItemColor: Colors.grey,
onTap: _onItemTapped,
),
);
}
}
home.dart에 대한 설명은 아래 링크 참조!
2023.07.04 - [공부기록/Flutter] - [Flutter] 반응형 모바일 배너 만들기(슬라이더)
home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<HomePage> {
final PageController _pageController = PageController();
int _currentPage = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
Expanded(
flex: 1,
child: Stack(
children: [
PageView(
controller: _pageController,
onPageChanged: (int page) {
setState(() {
_currentPage = page;
});
},
children: [
buildBanner('Banner 1', 0),
buildBanner('Banner 2', 1),
],
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
for (int i = 0; i < 2; i++)
Container(
margin: EdgeInsets.all(4.0),
width: 12.0,
height: 12.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _currentPage == i
? Colors.grey
: Colors.grey.withOpacity(0.5),
),
),
],
),
),
),
],
),
),
Expanded(
flex: 4,
child: Column(
children: [
Expanded(
child: Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10.0), // 원하는 둥근 정도를 설정합니다.
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
child: Text('2'),
),
),
Expanded(
child: Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10.0), // 원하는 둥근 정도를 설정합니다.
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
child: Text('2'),
),
),
],
),
),
],
),
),
);
}
Widget buildBanner(String text, int index) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0), // 원하는 둥근 정도를 설정합니다.
color: Colors.blueGrey,
),
child: Center(child: Text(text)),
);
}
}
tab1.dart
tab1.dart는 첫 번째 탭 페이지로, 간단한 리스트를 보여주는 페이지
페이지 상단에는 "탭1 리스트"라는 제목이 표시되고, 아래에는 아이템들의 목록이 ListView.builder를 통해 동적으로 생성된다.
각 아이템은 번호와 해당 아이템에 대한 세부 정보로 구성되어 표시된다.
tab1.dart, tab2.dart, tab3.dart
import 'package:flutter/material.dart';
class Tab1Page extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'탭1 리스트',
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
),
Expanded(
child: ListView.builder(
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item ${index + 1}'),
subtitle: Text('Details about Items ${index + 1}'),
);
},
),
),
],
),
);
}
}
위와 같은 방법으로 AppBar와 BottomNavigator는 고정하고 body만 변경되는 식으로 앱을 구현할 수 있다.
(정식으로 공부를 해서 작성하는 코드가 아니므로 더 좋은 방법이 있을 수 도 있습니다. 더 효율적인 방법이 있다면 댓글로 알려주시면 감사드리겠습니다!)
728x90
반응형
'공부기록 > Flutter' 카테고리의 다른 글
Flutter로 웹 앱 실행하기: 사용자 지정 호스트네임과 포트 설정 방법 (0) | 2023.07.08 |
---|---|
[Flutter] ListView 재사용하기(재사용 가능한 Widget 만들기) (0) | 2023.07.05 |
[Flutter] 반응형 모바일 배너 만들기(슬라이더) (0) | 2023.07.04 |
Flutter 유용한 Extensions(확장팩) 추천(Flutter Widget Snippets, Flutter Tree) (0) | 2023.07.02 |
Flutter 첫 시작! 설치부터 실행까지! (0) | 2023.07.01 |