Getx
pub.flutter-io.cn/packages/ge…
本節目標
- GetPage 物件
- 路由層級控制
- 路由中介軟體、鑑權
- 404 處理
- 路由跳轉、替換、清除
- 路由傳值、返回值
- 路由轉場動畫
開發環境
- Flutter 2.1.0-12.1.pre
- Dart 2.13.0
- get: ^3.26.0
參考
視訊
程式碼
正文
初始 getx 專案
- pubspec.yaml
dependencies:
...
get: ^3.26.0
複製程式碼
- lib/pages/home/index.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class HomeView extends StatelessWidget {
const HomeView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("首頁"),
),
body: ListView(
children: [
// 路由&導航
Divider(),
],
),
);
}
}
複製程式碼
- lib/common/routes/app_routes.dart
part of 'app_pages.dart';
abstract class AppRoutes {
static const Home = '/home';
}
複製程式碼
- lib/common/routes/app_pages.dart
import 'package:get/get.dart';
part 'app_routes.dart';
class AppPages {
static const INITIAL = AppRoutes.Home;
static final routes = [
GetPage(
name: AppRoutes.Home,
page: () => HomeView(),
),
];
}
複製程式碼
- lib/main.dart
Future<void> main() async {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
);
}
}
複製程式碼
編寫 GetPage 定義
- lib/pages/list/index.dart
class ListView extends StatelessWidget {
const ListView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("列表頁"),
),
);
}
}
複製程式碼
- lib/pages/list_detail/index.dart
class DetailView extends StatelessWidget {
const DetailView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("詳情頁"),
),
body: ListView(
children: [
ListTile(
title: Text("導航-返回"),
subtitle: Text('Get.back()'),
onTap: () => Get.back(),
),
],
),
);
}
}
複製程式碼
- lib/common/routes/app_routes.dart
abstract class AppRoutes {
static const Home = '/home';
static const List = '/list';
static const Detail = '/detail';
複製程式碼
- lib/common/routes/app_pages.dart
GetPage(
name: AppRoutes.Home,
page: () => HomeView(),
children: [
GetPage(
name: AppRoutes.List,
page: () => ListView(),
children: [
GetPage(
name: AppRoutes.Detail,
page: () => DetailView(),
),
],
),
],
),
複製程式碼
導航操作 命名、檢視物件
- lib/pages/home/index.dart
ListTile(
title: Text("導航-命名路由 home > list"),
subtitle: Text('Get.toNamed("/home/list")'),
onTap: () => Get.toNamed("/home/list"),
),
ListTile(
title: Text("導航-命名路由 home > list > detail"),
subtitle: Text('Get.toNamed("/home/list/detail")'),
onTap: () => Get.toNamed("/home/list/detail"),
),
ListTile(
title: Text("導航-類物件"),
subtitle: Text("Get.to(DetailView())"),
onTap: () => Get.to(DetailView()),
),
複製程式碼
導航-清除上一個
- lib/pages/home/index.dart
ListTile(
title: Text("導航-清除上一個"),
subtitle: Text("Get.off(DetailView())"),
onTap: () => Get.off(DetailView()),
),
複製程式碼
導航-清除所有
- lib/pages/home/index.dart
ListTile(
title: Text("導航-清除所有"),
subtitle: Text("Get.offAll(DetailView())"),
onTap: () => Get.offAll(DetailView()),
),
複製程式碼
導航-arguments 傳值+返回值
- lib/pages/home/index.dart
ListTile(
title: Text("導航-arguments傳值+返回值"),
subtitle: Text(
'Get.toNamed("/home/list/detail", arguments: {"id": 999})'),
onTap: () async {
var result = await Get.toNamed("/home/list/detail",
arguments: {"id": 999});
Get.snackbar("返回值", "success -> " + result["success"].toString());
},
),
複製程式碼
- lib/pages/list_detail/index.dart
_buildBackListTileRow(Map? val) {
return val == null
? Container()
: ListTile(
title: Text("傳值 id = " + val["id"].toString()),
subtitle: Text('Get.back(result: {"success": true}'),
onTap: () => Get.back(result: {"success": true}),
);
}
@override
Widget build(BuildContext context) {
final details = Get.arguments as Map;
final parameters = Get.parameters;
return Scaffold(
appBar: AppBar(
title: Text("詳情頁"),
),
body: ListView(
children: [
ListTile(
title: Text("導航-返回"),
subtitle: Text('Get.back()'),
onTap: () => Get.back(),
),
_buildBackListTileRow(details),
_buildBackListTileRow(parameters),
],
),
);
}
複製程式碼
導航-parameters 傳值+返回值
- lib/pages/home/index.dart
ListTile(
title: Text("導航-parameters傳值+返回值"),
subtitle: Text('Get.toNamed("/home/list/detail?id=666")'),
onTap: () async {
var result = await Get.toNamed("/home/list/detail?id=666");
Get.snackbar("返回值", "success -> " + result["success"].toString());
},
),
複製程式碼
- lib/pages/list_detail/index.dart
@override
Widget build(BuildContext context) {
final parameters = Get.parameters;
複製程式碼
導航-引數傳值+返回值
- lib/common/routes/app_routes.dart
static const Detail_ID = '/detail/:id';
複製程式碼
- lib/common/routes/app_pages.dart
...
GetPage(
name: AppRoutes.Detail_ID,
page: () => DetailView(),
),
複製程式碼
- lib/pages/home/index.dart
ListTile(
title: Text("導航-引數傳值+返回值"),
subtitle: Text('Get.toNamed("/home/list/detail/777")'),
onTap: () async {
var result = await Get.toNamed("/home/list/detail/777");
Get.snackbar("返回值", "success -> " + result["success"].toString());
},
),
複製程式碼
導航-not found
- lib/pages/notfound/index.dart
class NotfoundView extends StatelessWidget {
const NotfoundView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("路由沒有找到"),
),
body: ListTile(
title: Text("返回首頁"),
subtitle: Text('Get.offAllNamed(AppRoutes.Home)'),
onTap: () => Get.offAllNamed(AppRoutes.Home),
),
);
}
}
複製程式碼
- lib/common/routes/app_routes.dart
static const NotFound = '/notfound';
複製程式碼
- lib/common/routes/app_pages.dart
static final unknownRoute = GetPage(
name: AppRoutes.NotFound,
page: () => NotfoundView(),
);
複製程式碼
- lib/main.dart
@override
Widget build(BuildContext context) {
return GetMaterialApp(
...
unknownRoute: AppPages.unknownRoute,
);
}
複製程式碼
導航-中介軟體-認證 Auth
- lib/pages/login/index.dart
class LoginView extends StatelessWidget {
const LoginView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("登入"),
),
body: ListTile(
title: Text("返回首頁"),
subtitle: Text('Get.offAllNamed(AppRoutes.Home)'),
onTap: () => Get.offAllNamed(AppRoutes.Home),
),
);
}
}
複製程式碼
- lib/pages/my/index.dart
class MyView extends StatelessWidget {
const MyView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("我的"),
),
body: ListTile(
title: Text("返回首頁"),
subtitle: Text('Get.offAllNamed(AppRoutes.Home)'),
onTap: () => Get.offAllNamed(AppRoutes.Home),
),
);
}
}
複製程式碼
- lib/common/routes/app_routes.dart
static const Login = '/login';
static const My = '/my';
複製程式碼
- lib/common/middleware/router_auth.dart
class RouteAuthMiddleware extends GetMiddleware {
@override
int priority = 0;
RouteAuthMiddleware({required this.priority});
@override
RouteSettings? redirect(String route) {
Future.delayed(Duration(seconds: 1), () => Get.snackbar("提示", "請先登入APP"));
return RouteSettings(name: AppRoutes.Login);
}
}
複製程式碼
- lib/common/routes/app_pages.dart
// 白名單
GetPage(
name: AppRoutes.Login,
page: () => LoginView(),
),
GetPage(
name: AppRoutes.My,
page: () => MyView(),
middlewares: [
RouteAuthMiddleware(priority: 1),
],
),
複製程式碼
- lib/pages/home/index.dart
ListTile(
title: Text("導航-中介軟體-認證Auth"),
subtitle: Text('Get.toNamed(AppRoutes.My)'),
onTap: () => Get.toNamed(AppRoutes.My),
),
複製程式碼
Transition 轉場動畫
- lib/common/routes/app_pages.dart
GetPage(
name: AppRoutes.Detail_ID,
page: () => DetailView(),
transition: Transition.downToUp,
),
複製程式碼
© 貓哥