Flutter의 각종 page를 구현하고, page간에 이동하는 Router라는 클래스를 작성했다.
import 'package:flutter/material.dart';
import 'package:smartnpay/page/create_group_page.dart';
import 'package:smartnpay/page/create_restaurant_page.dart';
import 'package:smartnpay/page/home_page.dart';
import 'package:smartnpay/page/join_group_page.dart';
import 'package:smartnpay/page/login_page.dart';
import 'package:smartnpay/page/member_list_page.dart';
import 'package:smartnpay/page/search_restaurant_page.dart';
import 'package:smartnpay/page/settings_page.dart';
import 'package:smartnpay/page/web_browser_page.dart';
class Router {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/home':
return MaterialPageRoute(builder: (_) => HomePage());
case '/login':
return MaterialPageRoute(builder: (_) => LoginPage());
case "/settings":
return MaterialPageRoute(builder: (_) => SettingsPage());
case "/members":
return MaterialPageRoute(builder: (_) => MemberListPage());
case "/createGroup":
return MaterialPageRoute(builder: (_) => CreateGroupPage());
case "/joinGroup":
return MaterialPageRoute(builder: (_) => JoinGroupPage());
case "/searchRestaurant":
return MaterialPageRoute(builder: (_) => SearchRestaurantPage());
case "/createRestaurant":
return MaterialPageRoute(builder: (_) => CreateRestaurantPage());
case "/browser":
var params = (settings.arguments as Map<String, dynamic>);
return MaterialPageRoute(builder: (_) => WebBrowserPage(params["url"]));
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(child: Text('No route defined for ${settings.name}')),
));
}
}
static startLoginPage(context) {
Navigator.pushNamedAndRemoveUntil(context, "/login", (_) => false);
}
static startHomePage(context) {
Navigator.pushNamedAndRemoveUntil(context, "/home", (_) => false);
}
static startWebBrowser(context, String url) {
Navigator.pushNamed(context, "/browser", arguments: {"url": url});
}
}
Router라는 이름보다는 AppNavigator라는 것도 좋을 것 같다. startWebBrowser 함수를 보면 url 파라미터를 전달하는 방식을 알 수 있다. startLoginPage와 startHomePage는 다른 페이지를 다 pop시키고 첫 페이지로 연다.
main.dart에서 generateRoute를 등록한다.
Widget _materialApp() {
return MaterialApp(
onGenerateTitle: (BuildContext context) => S.of(context).appName,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: _user == null ? LoginPage() : HomePage(),
onGenerateRoute: Router.generateRoute,
localizationsDelegates: [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
localeResolutionCallback: S.delegate.resolution(fallback: Locale("en", ""), withCountry: false),
);
}
home: _user == null ? LoginPage() : HomePage(),
onGenerateRoute: Router.generateRoute,
이 두 줄이 핵심이다. home: LoginPage()로 수정해서, LoginPage에서 스플래시를 보여주다, 비로그인 상태이면 로그인 widget을 보여주고, 로그인 상태이거나 새로 로그인하면 HomePage로 이동시키는 것이 자연스러워 보인다.
Android의 startActivityForResult, onActivityResult 같은 건 어떻게 할까? 호출하고 결과를 받을 때는 이렇게 한다.
_onSearch() async {
var result = (await Navigator.pushNamed(context, "/searchRestaurant")) as Map<String, dynamic>;
if (result != null) {
Log.e("result", result.toString());
(itemList[0] as DataItem).text = result["name"] as String;
(itemList[1] as DataItem).text = result["category"] as String;
(itemList[2] as DataItem).text = result["url"] as String;
(itemList[3] as DataItem).text = result["mapUrl"] as String;
if (itemList.length > 4) {
itemList.removeRange(4, itemList.length);
}
itemList.add(MenuTitle());
List<String> menuList = result["menu"];
for (var menu in menuList) {
var items = menu.split("\t");
itemList.add(MenuItem(items[0], items[1]));
}
setState(() {});
}
}
결과와 함께 페이지를 닫기는 아래처럼한다.
String homeUrl = "https://m.place.naver.com/restaurant/$id/home";
var result = {"url": homeUrl, "mapUrl": mapUrl, "name": name, "category": category, "menu": menuArray};
Navigator.pop(context, result);