플러터(Flutter)를 사용하면서 다양한 UI 컴포넌트를 활용할 수 있습니다. 그 중에서도 TabBar와 TabView는 매우 유용하지만, 때로는 성능과 사용자 경험(UX) 측면에서 부족함을 느낄 수 있습니다. 특히 탭 간 전환 시 느린 반응 속도로 인해 상태값 변경을 활용하기 어렵다는 점이 문제로 지적됩니다. 이러한 문제를 해결하기 위해 PageView를 사용하면 훨씬 빠르고 부드러운 전환 효과를 얻을 수 있습니다. 이번 블로그 글에서는 TabBar와 TabView의 문제점과 PageView를 활용한 개선 방법에 대해 알아보겠습니다.
TabBar와 TabView는 플러터에서 탭 기반 네비게이션을 구현할 때 주로 사용됩니다. 하지만 다음과 같은 문제점이 있습니다:
느린 전환 속도: 탭을 전환할 때 애니메이션이 느리게 작동하여 사용자가 탭 전환을 기다려야 하는 상황이 발생합니다.
상태 관리의 어려움: 탭 전환 시 상태값 변경이 원활하지 않아 복잡한 상태 관리가 필요합니다.
성능 저하: 많은 탭을 사용할 경우 렌더링 성능이 저하될 수 있습니다.
PageView는 이러한 문제를 해결할 수 있는 훌륭한 대안입니다. PageView는 수평 슬라이드 방식으로 페이지를 전환할 수 있으며, 전환 속도가 빠르고 상태 관리가 용이합니다.
빠른 전환 속도: 페이지 전환이 매우 부드럽고 빠르게 이루어져 사용자 경험이 향상됩니다.
간편한 상태 관리: 각 페이지는 독립적으로 상태를 관리할 수 있어 복잡한 상태 관리가 필요 없습니다.
우수한 성능: 많은 페이지를 사용할 경우에도 성능 저하가 적습니다.
아래는 PageView를 사용하여 간단한 탭 네비게이션을 구현하는 예제입니다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
TabController _tabController;
PageController _pageController = PageController();
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
_tabController.addListener(() {
if (_tabController.indexIsChanging) {
_pageController.jumpToPage(_tabController.index);
}
});
}
@override
void dispose() {
_tabController.dispose();
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TabBar and PageView Example'),
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.home), text: 'Home'),
Tab(icon: Icon(Icons.business), text: 'Business'),
Tab(icon: Icon(Icons.school), text: 'School'),
],
),
),
body: PageView(
controller: _pageController,
onPageChanged: (index) {
_tabController.animateTo(index);
},
children: [
Center(child: Text('Page 1')),
Center(child: Text('Page 2')),
Center(child: Text('Page 3')),
],
),
);
}
}
TabController: 탭의 상태를 제어합니다. length는 탭의 개수, vsync는 애니메이션 동기화를 위한 값입니다.
PageController: PageView의 현재 페이지를 제어합니다.
TabBar: AppBar의 하단에 위치하여 탭을 제공합니다.
PageView: 각 페이지를 슬라이딩으로 전환할 수 있게 합니다.
Listeners:
_tabController.addListener(): 탭이 변경될 때 PageView의 페이지를 변경합니다.
onPageChanged: PageView의 페이지가 변경될 때 TabBar의 탭을 변경합니다.
플러터에서 TabBar와 TabView 대신 PageView를 사용하면 전환 속도가 빨라지고 상태 관리가 용이해져 UX가 크게 개선됩니다. 특히 많은 탭을 사용할 때 성능 저하 문제를 해결할 수 있어 더 나은 사용자 경험을 제공할 수 있습니다. 프로젝트에서 TabBar와 TabView의 성능 문제가 발생한다면, PageView로의 전환을 고려해보세요.