본문 바로가기
프로그래밍/Flutter & Dart

Flutter - View, Bar 위젯

by 어느덧중반 2021. 8. 23.
반응형

Flutter로 앱개발을 하기 위해선 화면에 보여지는 위젯들을 입맛에 맞게 잘 구현할 줄 알아야 한다.

자주 사용되는 위젯을 정리해 보자.


요약 : SingleChildScrollView, ListView, GridView, PageView, AppBar/TabBar/TabBarView, BottomNavigationBar

 

SingleChildScrollView


Column 또는 ListBody를 이용해 위젯을 아래로 쭉 나열하다 보면 화면 크기를 넘어갈 때가 있다.
이 때 스크롤이 필요한데, SingleChildScrollView를 사용해보자
class _MyHomePageState extends State<MyHomePage> { static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold); @override Widget build(BuildContext context) { final items = List.generate(100, (i) => i).toList(); return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: SingleChildScrollView( child: ListBody( children: items.map((i) => Center( child: Text( '$i', style: optionStyle,) ) ).toList(), ) ), ); }

 

 

ListView


SingleChildScrollView와 ListBody 합친 ListView 사용해보자


body: ListView(
scrollDirection: Axis.vertical,
children: <Widget>[
ListTile(
leading: Icon(Icons.access_alarm),
title: Text('alarm'),
trailing: Icon(Icons.navigate_next),
onTap: () {},
),
ListTile(
leading: Icon(Icons.add_a_photo),
title: Text('photo'),
trailing: Icon(Icons.navigate_next),
onTap: () {},
),
ListTile(
leading: Icon(Icons.add_call),
title: Text('call'),
trailing: Icon(Icons.navigate_next),
onTap: () {},
),
ListTile(
leading: Icon(Icons.android),
title: Text('android'),
trailing: Icon(Icons.navigate_next),
onTap: () {},
),
],
),

 

 

GridView


열 수를 지정해서 그리드 형태로 표시하는 위젯


GridView.count() 생성자는 간단하게 그리드를 작성하게 해줌


body: GridView.count( crossAxisCount: 3, children: <Widget>[ Container( color: Colors.red, height: 100, width: 100, padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), ), Container( color: Colors.green, height: 100, width: 100, padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), ), Container( color: Colors.black54, height: 100, width: 100, padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), ), Container( color: Colors.purpleAccent, height: 100, width: 100, padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), ), Container( color: Colors.lime, height: 100, width: 100, padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), ), ], )





 

PageView


여러 페이지 좌우로 슬라이드하여 넘길 수 있는 위젯


body: PageView( children: <Widget>[ Container( color: Colors.cyan ), Container( color: Colors.pinkAccent ), Container( color: Colors.blueAccent ), ], )

 

 

AppBar, TabBar, Tab, TabBarView


페이지와 탭 연동되는 화면 구현할 때 혼합해서 사용 가능


주의할 것은 Scaffold를 DefaultTabController로 꼭 감싸야 한다!!!!


return DefaultTabController( length: 4, // 탭수는 4개 child: Scaffold( appBar: AppBar( title: Text('Tab 혼합구현'), bottom: TabBar( tabs: <Widget>[ Tab(icon: Icon(Icons.add_a_photo)), Tab(icon: Icon(Icons.email)), Tab(text: '텍스트탭'), Tab(icon: Icon(Icons.more_horiz), text: '더보기'), ], ) ), body: TabBarView( children: <Widget>[ Container(color: Colors.deepOrange), Container(color: Colors.blue), Container(color: Colors.lime), Container(color: Colors.black), ], ) ), );

 

 

BottomNavigationBar


하단에 2~5개의 탭메뉴 구성하는 위젯. 각 탭 클릭으로 화면전환시 사용
class _MyHomePageState extends State<MyHomePage> { int _selectedIndex = 0; static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold); static const List<Widget> _widgetOptions = <Widget>[ Text( 'Index 0: Home', style: optionStyle, ), Text( 'Index 1: profile', style: optionStyle, ), Text( 'Index 2: call', style: optionStyle, ), ]; void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: _widgetOptions.elementAt(_selectedIndex), ), bottomNavigationBar: BottomNavigationBar( items: const <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: Icon(Icons.home), title: Text('home'), ), BottomNavigationBarItem( icon: Icon(Icons.people), title: Text('profile') ), BottomNavigationBarItem( icon: Icon(Icons.call), title: Text('call') )], currentIndex: _selectedIndex, selectedItemColor: Colors.amber[800], onTap: _onItemTapped, ), ); } }

 

 

 

 

반응형

댓글