플러터에서 탭바를 이용하다 보면, 다른 탭에 갔다가 오게 되면 스크롤 위치가 초기화되는 현상이 있습니다. 스크롤을 유지하기 위해서는 별도의 옵션을 주고 처리해야 합니다. 다만, 각 탭 이동시 렌더링은 이후 계속 유지하고 있습니다.
`StatefulWidget`에서 오버라이드(override)를 활용하여 `wantKeepAlive` 옵션을 `true` 값을 주면 됩니다.
예제
/// 탭바 위젯
class TabbarWidget extends GetView<TabbarController> {
const TabbarWidget({super.key});
@override
Widget build(BuildContext context) {
return Obx(
() => TabBar(
controller: controller.tabController.value,
isScrollable: true,
labelColor: Colors.red,
unselectedLabelColor: Colors.grey.shade800,
labelPadding: const EdgeInsets.symmetric(horizontal: 15),
indicatorPadding: const EdgeInsets.only(
left: 10,
right: 10,
),
indicator: UnderlineTabIndicator(
borderSide: BorderSide(
width: 3.w,
color: Colors.red,
),
),
labelStyle: TextStyle(
fontSize: 14.sp,
),
onTap: (value) {
// 탭바 인덱스 변경
},
tabs: List.generate(
controller.tabMenuData.length,
(index) => SizedBox(
height: 42.w,
child: Tab(
text: controller.tabMenuData[index].gnbName,
),
),
),
),
);
}
}
/// 레이아웃 위젯
class LayoutWidget extends StatefulWidget {
const TabbarWidget({
super.key,
required this.index,
});
final int index;
@override
State<LayoutWidget> createState() => _LayoutWidgetState();
}
class _LayoutWidgetState extends State<LayoutWidget>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
child: ContentWidget(index: widget.index),
);
}
}
/// 컨텐츠 위젯
class ContentWidget extends GetView<TabbarController> {
const ContentWidget({
super.key,
required this.index,
});
final int index;
@override
Widget build(BuildContext context) {
return Obx(
() => ListView.builder(
controller: controller.scrollController[index],
physics: const AlwaysScrollableScrollPhysics(),
itemCount: controller.data[index].length,
itemBuilder: (context, doubleIndex) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: List.generate(
controller.data[index].item[doubleIndex].length,
(templateIndex) {
/// 위젯 결과 리턴
},
),
);
},
),
);
}
}
728x90
사업자 정보 표시
레플라 | 홍대기 | 경기도 부천시 부일로 519 화신오피스텔 1404호 | 사업자 등록번호 : 726-04-01977 | TEL : 070-8800-6071 | Mail : support@reafla.co.kr | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기
'Dart > Flutter' 카테고리의 다른 글
[Flutter] 플러터 `Rive` 적용하기 (0) | 2022.12.23 |
---|---|
[Flutter] `TextField`, `TextFormField` 특정 포커스(Focus) 위치하기 (0) | 2022.12.23 |
[Flutter] Location `Attempt to invoke interface method 'void'` 오류 해결하기 (0) | 2022.12.21 |
[Flutter] `Location` 위치 정보 가져오기 (0) | 2022.12.19 |
[Flutter] 플러터 `notification.metrics.axis == widget.axis: is not true` 해결하기 (0) | 2022.12.15 |