又過了好久课竣,一直拖著沒有寫Flutter相關(guān)的東西了。已經(jīng)快忘記的差不多了置媳,最近實(shí)在是比較忙于樟,項(xiàng)目上線雌贱、一點(diǎn)空都沒有竟贯,不過最近好了一點(diǎn),本來一月份上線的項(xiàng)目最近延期了佳遂,一大堆的方案要寫寥袭。實(shí)在沒頭緒路捧,先不寫了,搞一下之前遺忘的條碼項(xiàng)目传黄。
這里記錄下杰扫,路由封裝的原理。
話不多說 直接上源碼膘掰,我們現(xiàn)在看下flutter中的源碼是怎么寫的涉波?
核心看MaterialPageRoute 方法
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'page_transitions_theme.dart';
import 'theme.dart';
/// A modal route that replaces the entire screen with a platform-adaptive
/// transition.
///
/// For Android, the entrance transition for the page slides the page upwards
/// and fades it in. The exit transition is the same, but in reverse.
///
/// The transition is adaptive to the platform and on iOS, the page slides in
/// from the right and exits in reverse. The page also shifts to the left in
/// parallax when another page enters to cover it. (These directions are flipped
/// in environments with a right-to-left reading direction.)
///
/// By default, when a modal route is replaced by another, the previous route
/// remains in memory. To free all the resources when this is not necessary, set
/// [maintainState] to false.
///
/// The `fullscreenDialog` property specifies whether the incoming page is a
/// fullscreen modal dialog. On iOS, those pages animate from the bottom to the
/// top rather than horizontally.
///
/// The type `T` specifies the return type of the route which can be supplied as
/// the route is popped from the stack via [Navigator.pop] by providing the
/// optional `result` argument.
///
/// See also:
///
/// * [PageTransitionsTheme], which defines the default page transitions used
/// by [MaterialPageRoute.buildTransitions].
class MaterialPageRoute<T> extends PageRoute<T> {
/// Construct a MaterialPageRoute whose contents are defined by [builder].
///
/// The values of [builder], [maintainState], and [fullScreenDialog] must not
/// be null.
MaterialPageRoute({
@required this.builder,
RouteSettings settings,
this.maintainState = true,
bool fullscreenDialog = false,
}) : assert(builder != null),
assert(maintainState != null),
assert(fullscreenDialog != null),
assert(opaque),
super(settings: settings, fullscreenDialog: fullscreenDialog);
/// Builds the primary contents of the route.
final WidgetBuilder builder;
@override
final bool maintainState;
@override
Duration get transitionDuration => const Duration(milliseconds: 300);
@override
Color get barrierColor => null;
@override
String get barrierLabel => null;
@override
bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
// Don't perform outgoing animation if the next route is a fullscreen dialog.
return (nextRoute is MaterialPageRoute && !nextRoute.fullscreenDialog)
|| (nextRoute is CupertinoPageRoute && !nextRoute.fullscreenDialog);
}
@override
Widget buildPage(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
final Widget result = builder(context);
assert(() {
if (result == null) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('The builder for route "${settings.name}" returned null.'),
ErrorDescription('Route builders must never return null.')
]);
}
return true;
}());
return Semantics(
scopesRoute: true,
explicitChildNodes: true,
child: result,
);
}
@override
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
final PageTransitionsTheme theme = Theme.of(context).pageTransitionsTheme;
return theme.buildTransitions<T>(this, context, animation, secondaryAnimation, child);
}
@override
String get debugLabel => '${super.debugLabel}(${settings.name})';
}
builder 不能為空,builder是什么炭序?我們來找一下啤覆。這里定義的builder可以理解為是一種BuildContext
/// Builds the primary contents of the route.
final WidgetBuilder builder;
typedef WidgetBuilder = Widget Function(BuildContext context);
/// Signature for a function that creates a widget for a given index, e.g., in a
/// list.
///
/// Used by [ListView.builder] and other APIs that use lazily-generated widgets.
///
/// See also:
///
/// * [WidgetBuilder], which is similar but only takes a [BuildContext].
/// * [TransitionBuilder], which is similar but also takes a child.
/**
* @Author: zhouge
* @Description: 路由
* @Date: Created in 19:38 2021-01-02
* @Modified By:
**/
import 'package:SmartCode/Pages/login/LoginPage.dart';
import 'package:SmartCode/Pages/Purchasepage.dart';
import 'package:SmartCode/Pages/Salespage.dart';
import 'package:SmartCode/Pages/WareHousePage.dart';
import 'package:SmartCode/Pages/Workpage.dart';
import 'package:flutter/material.dart';
import 'package:SmartCode/Pages/Settingpage.dart';
import 'package:SmartCode/Homepage.dart';
class Router {
//路由設(shè)置
static final _routes = {
"/": (context,{Object args}) => LoginPages(),
'/settings': (context,{Object args}) => SettingPages(),
'/purchase': (context,{Object args}) => PurchasePages(),
'/sales': (context,{Object args}) => SalesPages(),
'/warehouse': (context,{Object args}) => WareHousePages(),
'/work': (context,{Object args}) => WorkPages(),
'/home': (context,{Object args}) => HomePages(),
};
//監(jiān)聽route,類似于攔截器原理
Function getRoutes = (RouteSettings settings){
print(settings); //驗(yàn)證是否有效
final routeName = settings.name;
final Function builder = _routes[routeName];
Route route;
if (builder == null){
return route;
}else{
route = MaterialPageRoute(builder:(context) => builder(context,args:settings.arguments));
}
return route;
};
}
打印信息查看
image.png
目前沒有帶參數(shù)惭聂,null是空窗声,表示沒有傳遞參數(shù)進(jìn)來。
main入口辜纲,直接調(diào)用路由函數(shù)getRoutes獲取笨觅。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:SmartCode/routes/routes.dart';
//初始化路由
final Router router = Router();
void main() => runApp(MyApp());
final String SUPPLIER_URL = 'http://192.168.0.12';
final String SMART_URL = 'http://192.168.0.13/ws/web/r/awsp900';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
debugShowCheckedModeBanner: false,
initialRoute: '/',
onGenerateRoute:router.getRoutes,
);
}
}
另外,這里的顯示還是有點(diǎn)問題耕腾,需要單獨(dú)處理一下见剩。將首頁的顯示進(jìn)行一個(gè)封裝。這樣是無法直接進(jìn)入到每個(gè)頁面扫俺。有空在處理一下苍苞。