Flutter 학습 4: Flutter 개발 기본 사항 (3) 라우팅 관리

목차

0 서문

1 라우팅 관리

 1.1 MaterialPage 경로

1.2 네비게이터

 1.2.1 향후 푸시(BuildContext 컨텍스트, 경로 경로)

1.2.2 bool pop(BuildContext 컨텍스트, [ 결과 ])

1.2.3 향후 pushNamed(BuildContext 컨텍스트, 문자열 경로 이름,{객체 인수})

1.3 명명되지 않은 경로 전달 값

1.4 명명된 라우팅

 1.4.1 라우팅 테이블

1.4.2 라우팅 테이블 등록

1.4.3 라우팅 이름을 통해 새로운 라우팅 페이지 열기

1.4.4 명명된 경로 매개변수 전달

1.4.5 명명되지 않은 경로 값 전송 적응 

1.5 경로 생성 후크

1.6 요약


0 서문

이 글은 제2판|"Flutter in Practice·Second Edition"(flutterchina.club)의 서문에 대한 연구 및 요약입니다 .

1 라우팅 관리

  • Route는 일반적으로 모바일 개발에서 페이지를 의미하며 웹 개발에서 단일 페이지 애플리케이션의 Route와 동일한 개념적 의미를 갖습니다.
  • Route는 일반적으로 Android의 Activity와 iOS의 ViewController를 나타냅니다.
  • 소위 라우팅 관리는 페이지 사이를 이동하는 방법을 관리하는 것으로, 일반적으로 탐색 관리라고도 합니다.
  • Flutter의 라우팅 관리는 기본 개발과 유사합니다. Android이든 iOS이든 탐색 관리는 라우팅 스택을 유지합니다. 라우팅 푸시 작업은 새 페이지 열기에 해당하고 라우팅 팝 작업은 페이지 닫기 작업에 해당합니다. 라우팅 관리 주로 라우팅 스택을 관리하는 방법을 나타냅니다.

 1.1 MaterialPage 경로

MaterialPageRoutePageRoute클래스 에서 상속받은 PageRoute클래스는 전체 화면 공간을 차지하는 모달 라우팅 페이지를 나타내는 추상 클래스이며, 라우팅 구성 및 전환 시 전환 애니메이션에 대한 관련 인터페이스 및 속성을 정의합니다. MaterialPageRoute Material 구성 요소 라이브러리에서 제공하는 라우팅 구성 요소로, 다양한 플랫폼의 플랫폼 페이지 전환 애니메이션 스타일과 일치하는 라우팅 전환 애니메이션을 구현할 수 있습니다 .

  • Android의 경우 새 페이지가 열리면 새 페이지가 화면 하단에서 화면 상단으로 슬라이드되고, 페이지를 닫으면 현재 페이지가 화면 상단에서 화면 하단으로 슬라이드됩니다. 화면이 사라진 후 이전 페이지가 화면에 표시됩니다.
  • iOS의 경우 페이지가 열리면 모든 새 페이지가 화면에 표시될 때까지 새 페이지가 화면 오른쪽 가장자리에서 화면 왼쪽으로 슬라이드되고, 이전 페이지는 현재 화면에서 화면 왼쪽으로 슬라이드됩니다. 페이지를 닫으면 그 반대가 됩니다. 현재 페이지는 화면 오른쪽에서 슬라이드 아웃되고, 이전 페이지는 화면 왼쪽에서 슬라이드 인됩니다.
  • 경로 전환 애니메이션을 사용자 정의하려면 PageRoute를 직접 상속하여 구현할 수 있습니다.
MaterialPageRoute({
    /*
      用于构建路由页面的具体内容,返回值是一个新路由的widget实例。
    */
    WidgetBuilder builder, 
    /*
      包含路由的配置信息,如路由名称、是否初始路由(首页)。
    */
    RouteSettings settings,
    /*
      是否维护原路由内存状态,默认true, 即当入栈一个新路由时,原来的路由仍然会被保存在内存中。
      如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为 false
    */
    bool maintainState = true,
    /*
      表示新的路由页面是否是一个全屏的模态对话框,在 iOS 中,
      如果fullscreenDialog为true,新页面将会从屏幕底部滑入(而不是水平方向)
    */
    bool fullscreenDialog = false,
  })

1.2 네비게이터

  • Navigator라우팅 페이지를 열고 종료하는 방법을 제공하는 라우팅 관리 구성요소입니다 .
  • Navigator스택은 활성 경로 세트를 관리하는 데 사용됩니다.
  • 일반적으로 현재 화면에 표시되는 페이지는 스택 맨 위에 있는 경로입니다.

 1.2.1 향후 푸시(BuildContext 컨텍스트, 경로 경로)

이름 없는 경로 페이지 열기 : 지정된 경로를 스택에 푸시합니다(즉, 새 페이지 열기). 반환 값은 Future새 경로가 스택에서 팝될 때(즉, 닫힐 때 반환 데이터를 받는 데 사용되는 개체입니다.

1.2.2 bool pop(BuildContext 컨텍스트, [ 결과 ])

라우팅 페이지 닫기 : 스택에서 최상위 경로를 팝합니다.(즉, 현재 화면에 표시된 페이지를 닫습니다.) 반환 값은 bool 객체입니다. result 페이지가 닫힐 때 이전 페이지로 반환되는 데이터입니다.

1.2.3 향후 pushNamed(BuildContext 컨텍스트, 문자열 경로 이름,{객체 인수})

명명된 경로 페이지 열기 : 지정된 경로를 스택에 푸시합니다(즉, 새 페이지 열기). 반환 값은 Future새 경로가 스택에서 제거될 때(즉, 닫힐 때) 반환 데이터를 받는 데 사용되는 개체입니다.

1.3 명명되지 않은 경로 전달 값

/*
  创建一个TipRoute路由,它接受一个提示文本参数,负责将传入它的文本显示在页面上,
  另外TipRoute中添加一个“返回”按钮,点击后在返回上一个路由的同时会带上一个返回参数
*/
class TipRoute extends StatelessWidget {
  TipRoute({
    Key key,
    required this.text,  // 接收一个text参数
  }) : super(key: key);
  final String text;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("提示"),
      ),
      body: Padding(
        padding: EdgeInsets.all(18),
        child: Center(
          child: Column(
            children: <Widget>[
              Text(text),
              ElevatedButton(
                onPressed: () => Navigator.pop(context, "我是返回值"),
                child: Text("返回"),
              )
            ],
          ),
        ),
      ),
    );
  }
}


/*
  打开新路由TipRoute的代码:
*/
class RouterTestRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: () async {
          // 打开`TipRoute`,并等待返回结果
          var result = await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) {
                return TipRoute(
                  // 路由参数
                  text: "我是提示xxxx",
                );
              },
            ),
          );
          //输出`TipRoute`路由返回结果
          print("路由返回值: $result");
        },
        child: Text("打开提示页"),
      ),
    );
  }
}

1.4 명명된 라우팅

"Named Route"는 이름이 있는 경로입니다.

 1.4.1 라우팅 테이블

명명된 라우팅을 사용하려면 먼저 애플리케이션이 어떤 이름이 어떤 라우팅 구성 요소에 해당하는지 알 수 있도록 라우팅 테이블(라우팅 테이블)을 제공하고 등록해야 합니다.

라우팅 테이블의 정의: Map이며,

  • key는 문자열인 경로의 이름입니다.
  • 값은 해당 라우팅 위젯을 생성하는 데 사용되는 빌더 콜백 함수입니다.
  • 경로 이름을 통해 새 경로를 열면 애플리케이션은 경로 이름을 기반으로 라우팅 테이블에서 해당 WidgetBuilder 콜백 함수를 찾은 다음 콜백 함수를 호출하여 경로 위젯을 생성하고 반환합니다.
Map<String, WidgetBuilder> routes;

1.4.2 라우팅 테이블 등록

에서 속성 MaterialApp中추가 , 라우팅 테이블 등록routes

MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  //注册路由表
  routes:{
   "new_page":(context) => NewRoute(),
    ... // 省略其他路由注册信息
  } ,
  home: MyHomePage(title: 'Flutter Demo Home Page'),
);


/* 将home页面也注册为命名路由 */
MaterialApp(
  title: 'Flutter Demo',
  initialRoute:"/", //名为"/"的路由作为应用的home(首页)
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  //注册路由表
  routes:{
   "new_page":(context) => NewRoute(),
   "/":(context) => MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
  } 
);

1.4.3 라우팅 이름을 통해 새로운 라우팅 페이지 열기

onPressed: () {
  //打开命名路由页面
  Navigator.pushNamed(context, "new_page");

  //打开非命名路由页面
  //Navigator.push(context,
  //  MaterialPageRoute(builder: (context) {
  //  return NewRoute();
  //}));  
},

1.4.4 명명된 경로 매개변수 전달

/*
  1.先注册一个路由:
*/ 
routes:{
   "new_page":(context) => EchoRoute(),
  } ,

/*
  2.在路由页通过RouteSetting对象获取路由参数:
*/
class EchoRoute extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    //获取路由参数  
    var args=ModalRoute.of(context).settings.arguments;
    //...省略无关代码
  }
}

/*
  3.在打开路由时传递参数
*/
Navigator.of(context).pushNamed("new_page", arguments: "hi");

1.4.5 명명되지 않은 경로 값 전송 적응 

1.3 값 에 의한 Non-named 라우팅TipRoute 에서는 매개 text 변수를 허용하는데, 라우팅 테이블에 라우팅 페이지가 등록되어 있으면 소스 TipRoute코드를 TipRoute변경하지 않고 라우팅 이름을 통해 이를 열고 매개변수 전달을 구현하는 방법은 무엇입니까?

/*
  1.将TipRoute注册到路由表,同时传递text参数
*/
MaterialApp(
  routes: {
   "tip2": (context){
     return TipRoute(text: ModalRoute.of(context)!.settings.arguments.toString());
   },
 }, 
);

/*
  2.TipRoute源码,见【 1.3 非命名路由传值 】
*/

/*
  3.在打开路由时传递参数值
*/
Navigator.of(context).pushNamed("tip2", arguments: "你好吗");

1.5 경로 생성 후크

  • 경로 생성 후크는 MaterialApp다음의 onGenerateRoute속성을 참조합니다.
  • onGenerateRoute 명명된 경로에만 적용됩니다.
  • onGenerateRoute 명명된 경로를 열 때 호출될 수 있습니다. 명명 Navigator.pushNamed(...)된 경로를 열기 위해 호출할 때 지정된 경로 이름이 라우팅 테이블에 등록되어 있으면 라우팅 테이블의 함수가 호출되어 builder라우팅 구성 요소를 생성합니다. 라우팅 테이블에 등록되면 경로를 생성하기 위해 호출됩니다 onGenerateRoute.
  • onGenerateRoute 상황에 따라 라우팅에 대한 보다 자세한 작업을 수행하고 다른 페이지로 이동할 수 있습니다. 권한 제어도 수행할 수 있습니다.
  • onGenerateRoute 적용 가능한 시나리오의 예: 전자 상거래 앱을 개발한다고 가정합니다. 사용자가 로그인하지 않은 경우 상점, 제품 및 기타 정보를 볼 수 있지만 거래 기록, 장바구니, 사용자 개인 정보 및 기타 페이지는 기록되어야 합니다. 볼 수 있기 전에.
MaterialApp(
  ... //省略无关代码
  onGenerateRoute:(RouteSettings settings){
      //返回一个Route<dynamic>
	  return MaterialPageRoute(builder: (context){
		   String routeName = settings.name;
       /*
          如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,引导用户登录;
          其他情况则正常打开路由。
       */ 
     }
   );
  }
);

1.6 요약

 실제 개발에서는 다음과 같은 이점을 제공하는 명명된 라우팅 관리를 사용하는 것이 좋습니다.

  1. 의미가 더 명확해졌습니다.
  2. 코드는 유지 관리가 더 쉽습니다. 익명 라우팅을 사용하는 경우 Navigator.push호출되는 새 라우팅 페이지를 만들어야 합니다. 이를 위해서는 새 라우팅 페이지의 dart 파일을 가져와야 할 뿐만 아니라 이러한 코드도 매우 분산됩니다.
  3. onGenerateRoute전역 라우팅 점프 전처리 로직을 수행 할 수 있습니다 .

MaterialApp 라우팅에는 두 가지 콜백 속성 navigatorObservers도 있습니다.onUnknownRoute

  • navigatorObservers모든 라우팅 점프 동작을 모니터링할 수 있습니다.
  • onUnknownRoute존재하지 않는 명명된 경로를 열 때 호출됩니다.

추천

출처blog.csdn.net/D_lunar/article/details/131416195