본문 바로가기
  • 포르쉐타고싶다
인포테인먼트 - development/flutter

[flutter] bottomNavigationBar위에서 Hero 구현 : Hero와 Navigator의 관계(HeroController Observing)

by 지오ㄴl 2020. 10. 7.

bottomNavigationBar를 사용하고있고

그 안에서 네개의 탭이

각각의 Navigator를 가지고 있다.

그렇게 각각의 Navigator를 부여한 이유는

rootNavigator과 분리해야 rootNavigator에 존재하는 bottomNavigatorBar의 형태를 유지시킬 수 있기 때문이다.

 

하지만 각 탭에 새로운 Navigator를 '생으로' 적용하면

Navigation의 기능과 관련된 기능들이 사용되지 않을 수 있다.

 

내가 겪은 예는 바로 Hero이다.

Hero는 Navigation 도중 적용되는 기능 중 하나다.

하지만 생으로 만든 Navigator위에서 routing될 때 사용하면 

적용되지 않는다.

그에 반해, Navigator.of의 속성안에 rootNavigator: true 를 추가하면

Hero의 기능을 다시 볼 수 있다.

하지만! Navigate될 때 사용하는 Navigator가  rootNavigator이기 때문에

bottomNavigationBar가 사라져 포기해야된다.

 

그 이유는 Navigator는 기본적으로 HeroController가 없기때문이다.

적용되는 Navigator위에 HeroController가 observing하고있어야

rootNavigator를 사용하지 않고도

bottomNavigationBar를 유지시킨 채

Hero를 사용할 수 있다.

 

그렇다면 HeroController를 적용하는 방법을 보자
class TabNavigator extends StatelessWidget {
  TabNavigator({this.navigatorKey, this.tabItem});

  final GlobalKey<NavigatorState> navigatorKey;
  final StatefulWidget tabItem;

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      initialRoute: TabNavigatorRoutes.root,
      onGenerateRoute: (routeSettings) {
        return MaterialPageRoute(
          builder: (context) => tabItem,
        );
      },
    );
  }
}

위의 클래스는 내가 각각의 탭에 적용한 Navigator클래스이다.

이 Navigator는 HeroController를 observing하고있지 않아 그 위에서 Hero가 적용되지 않는다.

 

이 Navigator위에서 HeroController를 observing해보자

 

class TabNavigator extends StatelessWidget {
  TabNavigator({this.navigatorKey, this.tabItem});

  final GlobalKey<NavigatorState> navigatorKey;
  final StatefulWidget tabItem;

	//	HeroController 인스턴스 생성
  HeroController _heroController = HeroController(createRectTween: _createRectTween);

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      initialRoute: TabNavigatorRoutes.root,
      observers: [_heroController],		// HeroController Observe하기
      onGenerateRoute: (routeSettings) {
        return MaterialPageRoute(
          builder: (context) => tabItem,
        );
      },
    );
  }
}

// HeroController에 적용될 Tween 속성
RectTween _createRectTween(Rect begin, Rect end) {
  return MaterialRectArcTween(begin: begin, end: end);
}

 

이 Navigator를 bottomNavigationBar위에 있는 각각의 페이지 클래스에 적용하면

각각의 Navigator위에서 Hero를 적용할 수 있다.

반응형

댓글