본문 바로가기
프로그래밍/Flutter

[Flutter] 화면 전환 애니메이션 추가(Screen, Dialog)

by YuminK 2022. 6. 2.

MaterialPageRoute를 상속받아서 처리하는 방식으로 했다. 밑에 buldTransitions를 override해서 slide 애니메이션을 적용한다. (위 아래)

 

my_page_route.dart 

import 'package:flutter/material.dart';

SlideTransition getSlideTransition(Animation<double> animation, Widget child) {
  final tween = Tween(begin: const Offset(0.0, 1.0), end: Offset.zero);
  final offsetAnimation = animation.drive(tween);
  return SlideTransition(
    position: offsetAnimation,
    child: child,
  );
}

class MyPageRoute<T> extends MaterialPageRoute<T> {
  MyPageRoute({required WidgetBuilder builder, RouteSettings? settings})
      : super(builder: builder, settings: settings);

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    return getSlideTransition(animation, child);
  }
}

// Only pop animation, not start
class NoAnimationRoute extends MaterialPageRoute {
  NoAnimationRoute({builder}) : super(builder: builder);

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    Animation<double> onlyPopAnimation;
    switch (animation.status) {
      case AnimationStatus.reverse:
      case AnimationStatus.dismissed:
        onlyPopAnimation = animation;
        break;
      case AnimationStatus.forward:
      case AnimationStatus.completed:
        onlyPopAnimation = kAlwaysCompleteAnimation;
        break;
    }
    return getSlideTransition(onlyPopAnimation, child);
  }
}

 

Navigator에서 적용할 때

Navigator.push(
    context,
    MyPageRoute(
        builder: (context) =>
        ChangeNotifierProvider<LoginNotifier>.value(
            value: LoginNotifier(),
            child: const LoginScreen())));

 

showDialog는 내부 코드를 보면, Fade애니메이션이 기본으로 들어가있고 커스텀이 불가능한 형태로 되어 있다. 따라서 애니메이션을 추가하려면 showGeneralDialog를 사용해야 한다. 

 

# How to change showDialog to showGeneralDialog 
1. showGeneralDialog로 바꾼다. 
2. builder에서 하던 처리를 pageBuilder에 넣어줘야 한다. 
3. 각 처리하려는 화면에서 SafeArea를 설정해줘야 한다.
4. transitionBuilder에 대한 처리를 추가한다. (애니메이션)
5. then 처리는 그대로 옮긴다.

showDialog(
    useRootNavigator: false,
    barrierDismissible: false,
    context: context,
    builder: (context) => ChangeNotifierProvider<
        AddConfNotifier>.value(
        value: AddConfNotifier(context, ConfMode.edit, strRoomNo: notifier.strRoomNo),
        child: const AddConfScreen()))
    .then((result) {

});

showGeneralDialog(
  useRootNavigator: false,
  barrierDismissible: false,
  context: context,
  pageBuilder: (context, animation, secondAnimation) {
    return ChangeNotifierProvider<
        AddConfNotifier>.value(
        value: AddConfNotifier(context, ConfMode.edit, strRoomNo: notifier.strRoomNo),
        child: const AddConfScreen());
  },
  transitionBuilder: (context, animation, secondAnimation, child) {
    return getSlideTransition(animation, child);
  },
).then((result) {
 
});

댓글