추가 페이지 만들기 Navigator & Return 생략

Flutter

목록 보기
7/12

앱의 경우 새로운 페이지를 기존 페이지 위에 덮는 방식으로 사용.

  • 뒤로가기 버튼이 잘 먹음.
  • stack 형식 페이지 관리
          );
  • context 전달할 때 context에 Materialapp 의 정보가 담겨져있어야 한다.
  • MaterialPageRoute 안에 있는 위젯이 새로운 페이지로 사용됨.
  • 여기에 Scaffold 등의 위젯을 사용.
  • 길어지면 커스텀위젯으로 사용해서 만들기

leading 뒤로가기


기본적으로 상단 앱바 위젯에 뒤로가기가 생김.

  • leading 에 다른 위젯 추가시 자연스럽게 사라진다.

Return 생략

{} 안에 return 하나밖에 없으면 중괄호와 return을 동시에 생략가능

MaterialPageRoute(builder:(c){ return Text('새페이지');})
이 코드를

MaterialPageRoute(builder:(c) =>Text('새페이지'))
이렇게 생략 가능.

MaterialPageRoute()

  • 기본적인 페이지 + 애니메이션 전환
  • 오른쪽에서 왼쪽으로 들어오는 애니메이션 구현
  • 빌더함수를 통해 페이지를 추가한다.
  • 빌더에 return 되는 위젯으로 페이지 구성

PageRouteBuilder

  • 애니메이션을 지정하여 줄 수 있는 페이지 추가 버전
Navigator.push(
              context,
              PageRouteBuilder(
                pageBuilder: (context, animation, secondaryAnimation) => UploadPage(),
                transitionsBuilder: (context, animation, secondaryAnimation, child) {
                  // 새 페이지가 화면에 나타나는 애니메이션
                  var primaryBegin = Offset(0.0, 1.0);
                  var primaryEnd = Offset(0.0, 0.0);
                  var primaryCurve = Curves.ease;
                  var primaryTween = Tween(begin: primaryBegin, end: primaryEnd).chain(CurveTween(curve: primaryCurve));
                  var primaryAnimation = animation.drive(primaryTween);

                  // 이전 페이지가 화면에서 사라지는 애니메이션
                  var secondaryBegin = Offset(0.0, 0.0);
                  var secondaryEnd = Offset(-1.0, 0.0); // 왼쪽으로 사라지게 함
                  var secondaryCurve = Curves.ease;
                  var secondaryTween = Tween(begin: secondaryBegin, end: secondaryEnd).chain(CurveTween(curve: secondaryCurve));
                  var secondaryAnimationDriven = secondaryAnimation.drive(secondaryTween);

                  return Stack(
                    children: <Widget>[
                      SlideTransition(
                        position: secondaryAnimationDriven,
                        child: child,
                      ),
                      SlideTransition(
                        position: primaryAnimation,
                        child: child,
                      ),
                    ],
                  );
                },
              ),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
  // 새 페이지가 화면에 나타나는 애니메이션
  var primaryBegin = Offset(0.0, 1.0);   //	아래에서 올라옴
  var primaryEnd = Offset(0.0, 0.0);
  var primaryCurve = Curves.ease;	// 슬라이드를 할 속도 조절
  var primaryTween = Tween(begin: primaryBegin, end: primaryEnd).chain(CurveTween(curve: primaryCurve));
  var primaryAnimation = animation.drive(primaryTween);

  // 이전 페이지가 화면에서 사라지는 애니메이션
  var secondaryBegin = Offset(0.0, 0.0);
  var secondaryEnd = Offset(-1.0, 0.0); // 왼쪽으로 사라지게 함
  var secondaryCurve = Curves.ease;	// 슬라이드를 사용할 속도 조절
  // tween -> 실제 적용될 애니메이션의 집합체
  var secondaryTween = Tween(begin: secondaryBegin, end: secondaryEnd).chain(CurveTween(curve: secondaryCurve));
  var secondaryAnimationDriven = secondaryAnimation.drive(secondaryTween);

  return Stack(
    children: <Widget>[
      SlideTransition(
        position: secondaryAnimationDriven,
        child: child,
      ),
      SlideTransition(
        position: primaryAnimation,
        child: child,
      ),
    ],
  );
},

스택을 사용하여 애니메이션으로 두가지 슬라이드를 사용한다는 의미.
순서대로
1.secondary (원래 페이지) -> 아웃
2.primary (추가될 페이지) -> 인
이런방식으로 사용

Navigator.push(
  context,
  PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => NewPage(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
    
      var begin = Offset(0.0, 1.0);	//	아래에서 올라옴
      var end = Offset(0.0, 0.0);
      var curve = Curves.ease;	
      
      var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
      var offsetAnimation = animation.drive(tween);

      return SlideTransition(
        position: offsetAnimation,
        child: child,
      );
    },
  ),
);

animaion

  • 새로운 페이지가 적용될 애니메이션

secondaryAnimation

  • 원래 페이지가 적용될 애니메이션

begin = Offset(0.0,1.0);

  • 페이지가 아래서부터 시작함을 의미.

end = Offset(0.0,0.0)

  • 중앙에 페이지가 위치할 자리를 의미

Cureve

  • 페이지가 어떤 속도로 슬라이드할 지 고르는 것

Tween

  • 적용될 애니메이션들의 묶음

routes

페이지가 많을 경우 Routes 를 사용해서 처음부터 MaterialApp 위젯 작성.
라우터는 페이지가 많을 때 관리하기 편하려고 쓰는 것일 뿐

  • 첫 앱의 시작은 initialRoute로 지정해준 route 를 사용한다.
  • routes 안에 딕셔너리로 많은 페이지들을 url 과 매핑하여 사용
MaterialApp(
      theme: style.a,
      initialRoute: '/',
      routes : {
        '/' : (c) => Text('first'),
        '/detail' : (c) => Text('Seconde'),
      }
      // home: Myapp(),
    )

앱에서 url 이동

  • 웹에서는 가능한데, 앱에서는 힘듦
    버튼 onPressed 함수에
    Navigator.pushNamed(context, '/detail'); 함수 추가시 route 변경이 가능하다.

    라우터를 본격적으로 써야한다면 패키지 설치.

Vroute

VRouter 찾아 설치해서 쓰면 Vue, React의 라우터처럼 직관적인 페이지 나누기 가능.

가끔

/detail/1 입력 시 1번 게시물을 보여주고

/detail/2 입력 시 2번 게시물을 보여주는

그런 앱을 만들고 싶다면 onGenerateRoute 파라미터 사용.

MaterialApp(
      initialRoute: '/',
      onGenerateRoute: (settings) {
        var arguments = settings.arguments;
        if (settings.name == '/detail') {
          return MaterialPageRoute(builder: (context) => Upload(routeparam : arguments) );
        } else if (settings.name == '/') {
          return MaterialPageRoute(builder: (context) => Text('홈페이지') );
        } else {
          return null;
        }
      },
);

/detail/1 로 이동하면 routeparam이라는 파라미터가 1로 변하고

/detail/2 로 이동하면 routeparam이라는 파라미터가 2로 변합니다.

그리고 routeparam의 값은 Upload() 위젯 안에서 등록하고 사용가능합니다.

0개의 댓글