• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

강의를 보다 listview 기능에 의문이 생겨 질문드립니다.

22.03.30 11:22 작성 조회수 501

0

안녕하세요.

입문강의 시청 후 중급강의 시청 도중 의문이 생겨 질문 남겨봅니다.

 

ListView 를 사용하여 수백 수천개의 많은 수의 child를 생성하면 많이 버벅이더라구요.

이 부분은 원인을 찾았고 ListView.builder로 해결했지만

 

ListView builder를 사용하므로 다른 문제가 생겼습니다.

 

TabView 내부의 ListView builder를 사용하여 많은 child가 생성된 경우 다른탭으로 이동후 해당 탭으로 복귀 시

지연시간이 오래 걸리더라구요.

 

아마 많은 child를 랜더링한다고 생기는문제인거같은데 공식문서에 따르면 builder를 사용해야 재사용된다고 하던데 

이 문제는 어떻게 해결할 수 있나요?

 

- 많은 child를 가지고 있는 TabBar 내부의 한화면이 Tab을 이동 후 복귀해도 해당 포지션을 유지하고 Tab접환 시 지연이 없도록 하는 방법이 궁금합니다. (itemExtent를 통해 높이를 고정해주는 방법이 있던데 각각의 child의 높이를 다르게 설정하고 싶습니다.)

답변 1

답변을 작성해보세요.

1

ListView.builder 를 5만개의 정적인 데이터를 표시할 때는 느려지지 않았습니다.

표시하려는 데이터를 어떤 방식으로 얻고 있는지에 따라 느려지는 원인을 파악해야 할 것 같습니다.

포지션 유지는 ScrollController를 사용하시면 가능할 것 같습니다.

 

버거님의 프로필

버거

질문자

2022.03.31

안녕하세요 답변 감사합니다.

 

우선 제가 느려진다고 표현한 부분은 TabBar환경에서 예를들어

3개의 탭에서 첫번째 탭에 ListView.builder가 있고 거기에 많은 양의 정적인 데이터가 표시되고 있는 상태에서 

2번탭 또는 3번탭을 이동 후 다시 1번탭으로 복귀할 시 이동되기 전 딜레이가 걸립니다.

 

혹시 이 부분에 해결책이 있는지 궁금합니다.

이상하네요. 제가 테스트 했을 때 3개의 탭을 만들고 ListView.builder 로 5만개의 정적 데이터를 표시하는데 탭을 이동할 때 느려지지 않거든요.

뭔가 다른 요인이 있을 것 같은데요.

버거님의 프로필

버거

질문자

2022.04.01

안녕하세요. 답변 감사합니다.

 

우선 제가 상황 설명이 조금 부족했던것같습니다.

제가 설계하려는 화면의 조건은

TabBar

TabBar 내부의 Tab에 ListView가 있는(대량의 데이터) 화면

탭 이동 후 복귀 시 스크롤 위치 유지 - PageStorageKey 사용

이정도 입니다.

 

여기서 제가 말한 지연이 발생하는 조건은

ListView를 하단으로 스크롤 하여 많은 데이터가 화면에 표시됨(약 1천개 이상) 

다른 탭으로 이동 (이동이 완전히 멈춘 상태)

ListView 탭으로 복귀

입니다.

 

이 때 ListView에 그려진 아이템의 개수가 많아질수록 지연은 비례해서 길어지고있습니다.

 

기종의 차이일 수는 있지만 ios 보다는 android에서 지연시간이 길게 발생하고있습니다.

 

해당 이슈를 검색해봤을 때 자료는 많이 않았지만 해결방법으로 ListView의 itemExtent에 값을 명시적으로 부여하는것은데 이 방법을 사용할 경우 ListView 내부의 아이템의 높이가 모두 같게 고정됩니다.

하지만 많은 모바일 앱이 그렇듯 모든 아이템의 높이가 같은 경우는 드물기에 저도 이 방법 외의 방법이 궁금합니다.

 

지식인 앱이 flutter로 개발되었다고 하여 해당 앱으로 테스트해본 결과 해당 앱에서도 똑같은 이슈가 발생하고있었습니다.

(지식인 앱 -> 홈 화면 스크롤 하단의 '지식iN에서 배워요'의 전체보기 -> 아무 탭에서 스크롤 하단으로 이동하여 많은 아이템 생성 -> 다른 탭 이동 -> 해당 탭으로 복귀)

 

해당 이슈가 화면의 코드도 같이 남기겠습니다.

class ListBuilderTest extends StatefulWidget {
const ListBuilderTest({Key? key}) : super(key: key);

@override
State<ListBuilderTest> createState() => _State();
}

class _State extends State<ListBuilderTest> {

@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: const TabBar(
tabs: [Tab(text: "tab1"), Tab(text: "tab2"), Tab(text: "tab3")],
)),
body: TabBarView(
children: [
ListView.builder(
itemExtent: ,
key: const PageStorageKey(1),
itemCount: 50000,
itemBuilder: (BuildContext context, int index) {
return Text("$index");
},
),
const Text("tab2"),
const Text("tab3")
],
)));
}
}

보내주신 코드로 해 봤을 때도 저는 느려지지 않았습니다.

아니면 pagenation을 도입하시는 것도 하나의 방법일 듯 싶습니다.

https://pub.dev/packages/infinite_scroll_pagination