본문 바로가기
Flutter/Flutter FAQ

Flutter - TabBarView 내부의 ListView는 스크롤 위치를 잃어버립니다., Flutter - ListView inside on a TabBarView loses its scroll position

by 베타코드 2023. 10. 3.
반응형

질문


나는 TabBarView가 있는 매우 간단한 Flutter 앱을 가지고 있다. 두 개의 뷰(탭 1탭 2) 중 하나인 탭 1은 많은 간단한 텍스트 위젯을 가진 ListView가 있다. 문제는 탭 1의 ListView 요소를 아래로 스크롤한 후, 탭 1에서 탭 2로 스와이프하고 마지막으로 탭 2에서 탭 1로 스와이프하면, 탭 1의 ListView의 이전 스크롤 위치가 손실된다.

다음은 코드입니다:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late TabController controller;

  @override
  void initState() {
    super.initState();
    controller = TabController(
      length: 2,
      vsync: this,
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var tabs = const <Tab>[
      Tab(icon: Icon(Icons.home), text: 'Tab 1'),
      Tab(icon: Icon(Icons.account_box), text: 'Tab 2')
    ];

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: TabBarView(controller: controller, children: <Widget>[
        ListView(children: <Widget>[
          Column(children: <Widget>[
            for (int i = 0; i < 48; i++) Text('Data $i'),
          ])
        ]),
        const Center(child: Text('Tab 2'))
      ]),
      bottomNavigationBar: Material(
        color: Colors.deepOrange,
        child: TabBar(controller: controller, tabs: tabs),
      ),
    );
  }
}

나는 심지어 TabBarViewchildrens (Tab 1과 Tab 2)를 다른 클래스로 분리했고, 각 자식 (Tab 1과 Tab 2)의

@override
  Widget build(BuildContext context) {
  ...
}

메소드가 해당 컨테이너 탭으로 스와이프할 때마다 실행됨을 알았다.

내 질문은 다음과 같다:

1.- 탭 간에 이동해도 ListView의 스크롤을 유지하는 방법은 무엇인가요?

2.- TabBarView childrens (Tab 1과 Tab 2)를 다른 클래스로 분리하면,

@override
Widget build(BuildContext context) {

}

메소드를 한 번만 실행할 수 있는 방법이 있을까요? 즉, Tab 1과 Tab 2가 생성될 때마다 데이터를 검색해야 한다면, 해당 탭이 스와이프될 때마다 이 작업을 수행하고 싶지 않습니다. 이렇게 하면 비용이 많이 들 것입니다.

3.- 일반적으로, 탭 뷰 (변수, 데이터 등을 포함한)가 스와이프할 때마다 다시 빌드되지 않도록 방지하는 방법이 있을까요?

미리 감사드립니다.


답변


각 TabBarView에 PageStorageKey를 제공하면 스크롤 오프셋이 저장됩니다. 여기에서 PageStorageKey에 대한 자세한 정보를 확인하세요.

반응형

댓글