일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Babel standalone
- Redux
- web track
- FirebaseAnalytics
- userevent_tracker
- swagger-typescript-api
- code editor
- Excel
- node
- babel
- identifierForVender
- Image Resize typescript
- Three-fiber
- Completer
- REST API
- Flutter
- methodChannel
- Three js
- typescript
- react
- androidId
- Prism.js
- uint16array
- KakaoMap
- Raycasting
- Game js
- uint8array
- RouteObserver
- jszip
- webrtc
- Today
- Total
Never give up
Flutter - PageView with TabBar and Indicator 본문
Pageview를 활용할 방법은 여러가지가 있습니다
그 중 tabbar를 이용해서 pageview의 page와 tabbar의 tab을 일치시키는 예제
그리고 indicator로 페이지를 표시해 주는 예제를 다뤄보겠습니다
tabbar예제
class _PageViewExampleState extends State<PageViewExample>
with SingleTickerProviderStateMixin {
int _page = 0;
PageController _pController;
TabController _tController;
@override
void initState() {
super.initState();
_pController = PageController();
_tController = TabController(length: 3, vsync: this);
}
@override
void dispose() {
_pController?.dispose();
_tController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('PageView example'),
bottom: TabBar(
controller: _tController,
onTap: (value) {
_page = value;
_pController.animateToPage(_page,
duration: Duration(milliseconds: 300), curve: Curves.ease);
},
tabs: [
Tab(icon: Icon(Icons.looks_one_rounded)),
Tab(icon: Icon(Icons.looks_two_rounded)),
Tab(icon: Icon(Icons.looks_3_rounded)),
],
),
),
body: PageView(
controller: _pController,
scrollDirection: Axis.vertical,
onPageChanged: (value) {
_page = value;
_tController.animateTo(_page,
duration: Duration(milliseconds: 300), curve: Curves.ease);
},
children: [
_container(1, Colors.red),
_container(2, Colors.green),
_container(3, Colors.blue),
],
),
);
}
Container _container(int page, Color color){
return Container(
color: color,
child: Center(
child: Text(
'Page $page',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 24),
)));
}
}
Pageview의 direction을 수직으로 설정해주면
위아래로 드래그를 통해 다른 페이지로 이동할 수 있게 되고
onPageChanged에서 TabController를 이용해서
현재 페이지(page 값)와 동일한 tab으로 이동시켜줍니다
그리고 tabbar에서 터치를 통해 다른 화면으로 이동할때는
onTap에서 PageController를 이용해서 해당 페이지로 이동시켜줍니다
indicator예제
PageController _pController = PageController();
StreamController _sController = StreamController<int>()..add(0);
@override
void dispose() {
_sController?.close();
_pController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('PageView example 2')),
body: Stack(
children: [
PageView(
controller: _pController,
scrollDirection: Axis.horizontal,
onPageChanged: (value) {
_sController.add(value);
},
children: [
_container(1, Colors.red),
_container(2, Colors.green),
_container(3, Colors.blue),
],
),
Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 50,
width: 50,
child: StreamBuilder<int>(
stream: _sController.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 3,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.symmetric(
vertical: 8, horizontal: 4),
width: 9,
height: 9,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: (snapshot.data == index)
? Colors.white
: Colors.grey),
);
});
}
return Container();
})),
),
],
),
);
}
Container _container(int page, Color color) {
return Container(
color: color,
child: Center(
child: Text(
'Page $page',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24),
)));
}
위 예제와 거의 동일한데 여기서는 direction을 수평으로 해줬고
page의 이동에 따라 dot indicator로 움직임을 표현해 보는 예제를 만들어 봤습니다
Pageview의 onPageChanged부분에서 값을 StreamController를 이용해서 page값을 전달합니다
그리고 Streambuilder를 통해 ListView의 아이템 index와 page값이 동일할 때
아이템 색깔을 하얀색으로 동일하지 않을 때 회색으로 해서
현재 페이지가 어디에 있는지 그리고 총 페이지 수가 얼마나 되는지 표현할 수 있습니다
StreamBuilder를 사용하는대신 onPageChanged 부분에 setState로 페이지 변경을
notify해주는 방법도 있지만 나중에 Page부분에 데이터가 많아지면 rebuild할 때 문제가 발생할 수도 있으니
StreamBuilder를 사용하는 연습을 해보는것도 좋을거 같습니다
'Flutter' 카테고리의 다른 글
Flutter - How to use exntension with getting widget position (0) | 2021.02.07 |
---|---|
Flutter - update previous screen with Navigator callback (0) | 2021.01.05 |
Flutter - Provider Selector with tuple (3) | 2020.12.31 |
Flutter - CachedNetworkImageProvider error handling? (0) | 2020.12.29 |
Flutter - When you store collection in cloud firestore (0) | 2020.12.23 |