비동기 데이터로 랜더링되는 화면(ConsumerWidget)과 hero animation

ds-k.dev·2025년 1월 2일
0

TIL

목록 보기
26/26

개요

mainPage에서 영화 id와 image를 datailPage로 전달하고,
detailPage의 나머지 정보들은 AutodisposAsyncFamilyNotifierProvider을 consumerWidget으로 선언된 detailPage에서 ref.watch를 통해 불러오고, state.when을 통해 데이터를 그려주고 있는 상황이었다.

문제

분명 고유한 id로 양측 이미지에 heroTag를 불러줬는데, hero animation이 동작하지 않는 문제가 생겼다.

시도1(실패)

시도 1 commit

image를 불러오는 과정에서 shimmer 라이브러리를 이용해서 회색 배경을 먼저 보여주는 기능을 구현해 뒀는데, 이 때문에 애니메이션 동작에 문제가 생길수 있을 것 같아서 제거하고 테스트해보았지만 해결되지 않았다.

검색해보니 이미지 뿐만 아니라 태그만 같다면 어떤 위젯이든지 hero 애니메이션을 적용할 수 있다고 한다.

시도2(실패)

시도 2 commit

고유한 HeroTag를 만들기 위해 카테고리 명 - movieId (ex. 인기 순 - 123123) 으로 태그를 동적으로 생성하여 전달해주고 있었는데, 혹시 한글로 만든게 문제일까 싶어서 영어로 변경해줬지만 의미 없었다.

시도3(실패 but, 원인에 가까워짐)

시도 3 commit

문득, 전체가 consumerWidget으로 쌓여있고 ref.watch(provider)를 기다렸다가 화면을 그려주면 화면이 전환되는 그 시점에는 연결할 이미지 데이터가 존재하지 않아서 애니메이션이 안나올 것 같다는 생각이 들었다.(거의 확신에 가까운)

또한 추가적으로, 화면 이미지의 경우에는 Provier가 아니라 mainPage에서 바로 전달해주는 데이터인데, 전체를 ConsumerWidget으로 감쌀 필요가 없이 provider로부터 제공받는 영역만 consumer로 감싸주는 것이 더 효율적일 거라고 생각했다.

그러나, 이때 바로 되지는 않았다.

시도4(성공)

시도 4 commit

여러가지를 시도하던 중 ShimmerLoadingImage 안에 image파트 hero 태그를 전달하여 연결을 시도했었는데, 시도 1에서 알게된 사실처럼 굳이 image로 한 레벨 더 들어갈 필요없이 ShimmerLoadingImage 위젯 전체를 hero로 감싸주는게 맞다고 생각을 했고, 그 결과 성공하게 되었다.

알게 된 점

단순히 애니메이션이 안되서 이것을 해결하려던 것이였지만 배운 점이 많았다.

  1. hero 애니메이션을 연결할때는 연결 대상이 비동기 상태로 불러오는 친구인지 확인한다.
  2. 다짜고짜 consumerWidget으로 덮어버리기보다, 화면을 그리는 데이터의 출처가 동기인지 비동기인지 구분하여 사용하면 보다 랜더링이 깔끔해질 수 있다.

데이터가 어디서 오는지, 어떤식으로 화면이 랜더링되는지에 대해서 더 학습해서 가장 효율적으로 화면을 그릴 수 있도록 노력하자

0개의 댓글