├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ ├── .gitignore │ └── Podfile ├── raw │ ├── airoute_render_ios.gif │ ├── airoute_render_web.gif │ ├── airoute_render_macos.gif │ └── airoute_render_android.gif ├── macos │ ├── Runner │ │ ├── Configs │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ ├── Warnings.xcconfig │ │ │ └── AppInfo.xcconfig │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app_icon_16.png │ │ │ │ ├── app_icon_32.png │ │ │ │ ├── app_icon_64.png │ │ │ │ ├── app_icon_1024.png │ │ │ │ ├── app_icon_128.png │ │ │ │ ├── app_icon_256.png │ │ │ │ ├── app_icon_512.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Release.entitlements │ │ ├── DebugProfile.entitlements │ │ ├── MainFlutterWindow.swift │ │ ├── Info.plist │ │ └── Base.lproj │ │ │ └── MainMenu.xib │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Podfile.lock │ └── Podfile ├── android │ ├── gradle.properties │ ├── .gitignore │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── air │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ └── build.gradle ├── web │ └── index.html ├── .metadata ├── test │ └── widget_test.dart ├── .gitignore ├── lib │ ├── page │ │ ├── second_page.dart │ │ ├── third_page.dart │ │ └── launch_page.dart │ └── main.dart ├── pubspec.yaml ├── Fix.md ├── Fix_EN.md ├── pubspec.lock ├── README.md └── README_EN.md ├── README.md ├── lib ├── route │ ├── argument_receiver.dart │ ├── argument.dart │ ├── transition.dart │ ├── navigator_manager.dart │ ├── app.dart │ ├── route.dart │ └── airoute.dart └── airoute.dart ├── .metadata ├── test └── flutter_route_test.dart ├── LICENSE ├── .gitignore ├── pubspec.yaml ├── CHANGELOG.md ├── README_DETAIL.md ├── README-EN.md ├── pubspec.lock └── README_DETAIL-EN.md /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /example/raw/airoute_render_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/raw/airoute_render_ios.gif -------------------------------------------------------------------------------- /example/raw/airoute_render_web.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/raw/airoute_render_web.gif -------------------------------------------------------------------------------- /example/raw/airoute_render_macos.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/raw/airoute_render_macos.gif -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/raw/airoute_render_android.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/raw/airoute_render_android.gif -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Airoute 2 | 3 | 4 | 5 | 6 | ## LICENSE 7 | 8 | 9 | BSD 3-Clause License 10 | 11 | Copyright (c) 2020, pdliuw 12 | All rights reserved. 13 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/route/argument_receiver.dart: -------------------------------------------------------------------------------- 1 | part of airoute; 2 | 3 | /// 4 | /// ArgumentReceiver 5 | abstract class AirArgumentReceiver { 6 | void receive(AirArgument argument); 7 | } 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdliuw/airoute/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | example 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip 7 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f5733f7a62ebc7c2ba324a2b410cd81215956b7d 8 | channel: master 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 43a8a1902e5c42d084077e8ede6f14f8ddbdce24 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import webview_flutter_wkwebview 9 | 10 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 11 | FLTWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "FLTWebViewFlutterPlugin")) 12 | } 13 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FlutterMacOS (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - FlutterMacOS (from `Flutter/ephemeral/.symlinks/flutter/darwin-x64`) 6 | 7 | EXTERNAL SOURCES: 8 | FlutterMacOS: 9 | :path: Flutter/ephemeral/.symlinks/flutter/darwin-x64 10 | 11 | SPEC CHECKSUMS: 12 | FlutterMacOS: 15bea8a44d2fa024068daa0140371c020b4b6ff9 13 | 14 | PODFILE CHECKSUM: d8ba9b3e9e93c62c74a660b46c6fcb09f03991a7 15 | 16 | COCOAPODS: 1.8.4 17 | -------------------------------------------------------------------------------- /test/flutter_route_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | import 'package:airoute/airoute.dart'; 4 | 5 | void main() { 6 | test('adds one to input values', () { 7 | // final calculator = RouteManager.getInstance(); 8 | // expect(calculator.addOne(2), 3); 9 | // expect(calculator.addOne(-7), -6); 10 | // expect(calculator.addOne(0), 1); 11 | // expect(() => calculator.addOne(null), throwsNoSuchMethodError); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/airoute.dart: -------------------------------------------------------------------------------- 1 | library airoute; 2 | 3 | /// 4 | /// Import 5 | import 'dart:async'; 6 | import 'package:flutter/cupertino.dart'; 7 | import 'package:flutter/foundation.dart'; 8 | import 'package:flutter/material.dart'; 9 | 10 | /// 11 | /// Part 12 | part 'route/route.dart'; 13 | part 'route/argument_receiver.dart'; 14 | part 'route/argument.dart'; 15 | part 'route/app.dart'; 16 | part 'route/transition.dart'; 17 | part 'route/airoute.dart'; 18 | part 'route/navigator_manager.dart'; 19 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/air/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.air.example 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.android.FlutterActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.air.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2019 com.air. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.9.0' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.0.1' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Web related 33 | lib/generated_plugin_registrant.dart 34 | 35 | # Exceptions to above rules. 36 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 37 | -------------------------------------------------------------------------------- /lib/route/argument.dart: -------------------------------------------------------------------------------- 1 | part of airoute; 2 | 3 | /// 4 | /// Argument 5 | class AirArgument { 6 | AirArgument({ 7 | this.key, 8 | this.tag, 9 | this.routeName, 10 | this.argument, 11 | this.isInitialRoute = false, 12 | }); 13 | 14 | /// 15 | /// [key] is the primary id. 16 | Key? key; 17 | 18 | /// 19 | /// [tag] is the tag/flag. 20 | String? tag; 21 | 22 | /// 23 | /// [routeName] 24 | String? routeName; 25 | 26 | /// 27 | /// [isInitialRoute] 28 | bool? isInitialRoute; 29 | 30 | /// 31 | /// [argument] is the data. 32 | dynamic argument; 33 | 34 | @override 35 | String toString() { 36 | return "key:$key, tag:$tag, routeName:$routeName, argument:${argument.toString()}, isInitialRoute:$isInitialRoute"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/lib/page/second_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:airoute/airoute.dart'; 3 | 4 | /// 5 | /// SecondPage 6 | class SecondPage extends StatefulWidget with AirArgumentReceiver { 7 | dynamic _content; 8 | @override 9 | State createState() { 10 | return _SecondPageState(); 11 | } 12 | 13 | @override 14 | void receive(AirArgument argument) { 15 | _content = argument.argument; 16 | print("收到${argument.argument}参数了,我很开心😄😄😄"); 17 | } 18 | } 19 | 20 | /// 21 | /// _SecondPageState 22 | class _SecondPageState extends State { 23 | @override 24 | Widget build(BuildContext context) { 25 | return Scaffold( 26 | backgroundColor: Colors.blue, 27 | appBar: AppBar( 28 | elevation: 0, 29 | title: Text("SecondPage"), 30 | ), 31 | body: Center( 32 | child: Column( 33 | children: [ 34 | Text( 35 | "以下为上页传递的数据\n\n\n${widget._content}", 36 | style: TextStyle( 37 | color: Colors.white, 38 | ), 39 | textAlign: TextAlign.center, 40 | ), 41 | ElevatedButton.icon( 42 | onPressed: () { 43 | Airoute.pushNamed(routeName: "/ThirdPage", argument: "Air"); 44 | }, 45 | icon: Icon(Icons.arrow_right), 46 | label: Text("Next"), 47 | ), 48 | ], 49 | ), 50 | ), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, pdliuw 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/lib/page/third_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:airoute/airoute.dart'; 3 | 4 | /// 5 | /// ThirdPage 6 | class ThirdPage extends StatefulWidget with AirArgumentReceiver { 7 | dynamic _content; 8 | 9 | @override 10 | State createState() { 11 | return _ThirdPageState(); 12 | } 13 | 14 | @override 15 | void receive(AirArgument argument) { 16 | _content = argument.argument; 17 | print("收到${argument.argument}参数了,我很开心😄😄😄"); 18 | } 19 | } 20 | 21 | /// 22 | /// _SecondPageState 23 | class _ThirdPageState extends State { 24 | @override 25 | Widget build(BuildContext context) { 26 | return Scaffold( 27 | backgroundColor: Colors.blue, 28 | appBar: AppBar( 29 | elevation: 0, 30 | title: Text("ThirdPage"), 31 | ), 32 | body: Center( 33 | child: Column( 34 | children: [ 35 | Text( 36 | "以下为上页传递的数据\n\n\n${widget._content}", 37 | style: TextStyle( 38 | color: Colors.white, 39 | ), 40 | textAlign: TextAlign.center, 41 | ), 42 | ElevatedButton.icon( 43 | onPressed: () { 44 | Airoute.popUntil(untilRouteName: "/SecondPage"); 45 | }, 46 | icon: Icon(Icons.arrow_back), 47 | label: Text("Back"), 48 | ), 49 | ElevatedButton.icon( 50 | onPressed: () { 51 | Airoute.pushNamed(routeName: "/ThirdPage", argument: "Repeat"); 52 | }, 53 | icon: Icon(Icons.arrow_right), 54 | label: Text("Next"), 55 | ), 56 | ], 57 | ), 58 | ), 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/Flutter/flutter_export_environment.sh 65 | **/ios/ServiceDefinitions.json 66 | **/ios/Runner/GeneratedPluginRegistrant.* 67 | 68 | # Exceptions to above rules. 69 | !**/ios/**/default.mode1v3 70 | !**/ios/**/default.mode2v3 71 | !**/ios/**/default.pbxuser 72 | !**/ios/**/default.perspectivev3 73 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 74 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: airoute 2 | description: 1、Support routing management without context,2、Support 'non-intrusive parameter passing' routing management,3、Airoute that makes you fall in love with routing management 3 | version: 3.2.4 4 | homepage: https://pdliuw.github.io/ 5 | repository: https://github.com/pdliuw/airoute 6 | 7 | environment: 8 | sdk: ">=2.12.0 <3.0.0" 9 | flutter: ">=1.20.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | 19 | # For information on the generic Dart part of this file, see the 20 | # following page: https://dart.dev/tools/pub/pubspec 21 | 22 | # The following section is specific to Flutter. 23 | flutter: 24 | 25 | # To add assets to your package, add an assets section, like this: 26 | # assets: 27 | # - images/a_dot_burr.jpeg 28 | # - images/a_dot_ham.jpeg 29 | # 30 | # For details regarding assets in packages, see 31 | # https://flutter.dev/assets-and-images/#from-packages 32 | # 33 | # An image asset can refer to one or more resolution-specific "variants", see 34 | # https://flutter.dev/assets-and-images/#resolution-aware. 35 | 36 | # To add custom fonts to your package, add a fonts section here, 37 | # in this "flutter" section. Each entry in this list should have a 38 | # "family" key with the font family name, and a "fonts" key with a 39 | # list giving the asset and other descriptors for the font. For 40 | # example: 41 | # fonts: 42 | # - family: Schyler 43 | # fonts: 44 | # - asset: fonts/Schyler-Regular.ttf 45 | # - asset: fonts/Schyler-Italic.ttf 46 | # style: italic 47 | # - family: Trajan Pro 48 | # fonts: 49 | # - asset: fonts/TrajanPro.ttf 50 | # - asset: fonts/TrajanPro_Bold.ttf 51 | # weight: 700 52 | # 53 | # For details regarding fonts in packages, see 54 | # https://flutter.dev/custom-fonts/#from-packages 55 | -------------------------------------------------------------------------------- /lib/route/transition.dart: -------------------------------------------------------------------------------- 1 | part of airoute; 2 | 3 | /// 4 | /// AirouteTransition 5 | class AirouteTransition { 6 | /// 7 | /// default scale animation 8 | static Widget _scale( 9 | BuildContext? context, 10 | Animation? animation, 11 | Animation? secondaryAnimation, 12 | Widget? page, 13 | ) { 14 | return ScaleTransition( 15 | scale: animation!, 16 | alignment: Alignment.topRight, 17 | child: page, 18 | ); 19 | } 20 | 21 | /// 22 | /// default slide animation 23 | static Widget _slide( 24 | BuildContext? context, 25 | Animation? animation, 26 | Animation? secondaryAnimation, 27 | Widget? page, 28 | ) { 29 | return SlideTransition( 30 | position: Tween( 31 | begin: const Offset(1.0, 0.0), 32 | end: const Offset(0.0, 0.0), 33 | ).animate(animation!), 34 | child: page, 35 | ); 36 | } 37 | 38 | /// 39 | /// default fade animation 40 | static Widget _fade( 41 | BuildContext? context, 42 | Animation? animation, 43 | Animation? secondaryAnimation, 44 | Widget? page, 45 | ) { 46 | return FadeTransition( 47 | opacity: animation!, 48 | child: page, 49 | ); 50 | } 51 | 52 | /// 53 | /// default rotation animation 54 | static Widget _rotation( 55 | BuildContext? context, 56 | Animation? animation, 57 | Animation? secondaryAnimation, 58 | Widget? page, 59 | ) { 60 | return RotationTransition( 61 | turns: animation!, 62 | alignment: Alignment.center, 63 | child: page, 64 | ); 65 | } 66 | 67 | /// 68 | /// Slide 69 | static const RoutePageAnimation Slide = _slide; 70 | 71 | /// 72 | /// Fade. 73 | static const RoutePageAnimation Fade = _fade; 74 | 75 | /// 76 | /// Scale. 77 | static const RoutePageAnimation Scale = _scale; 78 | 79 | /// 80 | /// Rotation. 81 | static const RoutePageAnimation Rotation = _rotation; 82 | } 83 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [3.2.4] 2 | 3 | * adapter: flutter v3.2.4 4 | 5 | ## [3.0.0] 6 | 7 | * adapter: flutter v3.0.0 8 | 9 | ## [2.2.0] 10 | 11 | * upgrade: flutter: ">=1.20.0" 12 | 13 | ## [2.0.0] 14 | 15 | * Migrate to null safety. 16 | 17 | ## [1.0.0] - airoute 18 | 19 | * adapter: flutter version = 1.22 20 | 21 | ## [0.3.5] - airoute 22 | 23 | * fix something 24 | 25 | ## [0.3.3] - airoute 26 | 27 | * adapter: flutter version = 1.20 28 | 29 | ## [0.3.2] - airoute 30 | 31 | * adapter: 32 | flutter version = 1.17 33 | dart version = 2.8 34 | 35 | ## [0.2.3-pre.1.0] - preview 36 | 37 | * adapter: flutter version = 1.18.0-7.0,dart version = 2.9.0 38 | 39 | ## [0.2.3-pre-1.0] - preview 40 | 41 | * adapter: flutter version = 1.18.0-7.0,dart version = 2.9.0 42 | 43 | ## [0.2.3] - Route. 44 | 45 | * Fix: 'isInitialRoute' isn't defined for the class 'RouteSettings' on flutter-v1.15.23 46 | 47 | ## [0.2.2] - Route. 48 | 49 | * Update: example 50 | 51 | ## [0.2.1] - Route. 52 | 53 | * Fix: Occasional 'observer.navigator == null': is not true.! 54 | 55 | ## [0.2.0] - Route. 56 | 57 | * Add: Push route! 58 | 59 | ## [0.1.9] - Route. 60 | 61 | * Default anim: AirouteTransition.Fade! 62 | 63 | ## [0.1.8] - Route. 64 | 65 | * Fix: something! 66 | 67 | ## [0.1.7] - Route. 68 | 69 | * Fix: something! 70 | 71 | 1 、Duration 72 | 73 | Error:Failed assertion: line 130 pos 12: 'duration != null && duration >= Duration.zero': is not true. 74 | Issues:https://github.com/pdliuw/airoute/issues/3 75 | 76 | ## [0.1.6] - Route. 77 | 78 | * Improve: Improve health 79 | 80 | ## [0.1.5] - Route. 81 | 82 | * Add: CupertinoApp 、 WidgetsApp 83 | 84 | ## [0.1.4] - Route. 85 | 86 | * Update: AirArgument. 87 | 88 | ## [0.1.3] - Route. 89 | 90 | * Fix: shortcuts actions. 91 | 92 | ## [0.1.2] - Route. 93 | 94 | * Add: repository. 95 | 96 | ## [0.1.1] - Route. 97 | 98 | * Support: argument. 99 | 100 | ## [0.0.1] - Route. 101 | 102 | * Support: manager route without context. 103 | * Support: global config. 104 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | compileSdk = 34 31 | 32 | sourceSets { 33 | main.java.srcDirs += 'src/main/kotlin' 34 | } 35 | 36 | lintOptions { 37 | disable 'InvalidPackage' 38 | } 39 | 40 | defaultConfig { 41 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 42 | applicationId "com.air.example" 43 | minSdkVersion flutter.minSdkVersion 44 | targetSdkVersion 28 45 | versionCode flutterVersionCode.toInteger() 46 | versionName flutterVersionName 47 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 48 | } 49 | 50 | buildTypes { 51 | release { 52 | // TODO: Add your own signing config for the release build. 53 | // Signing with the debug keys for now, so `flutter run --release` works. 54 | signingConfig signingConfigs.debug 55 | } 56 | } 57 | } 58 | 59 | flutter { 60 | source '../..' 61 | } 62 | 63 | dependencies { 64 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 65 | testImplementation 'junit:junit:4.12' 66 | androidTestImplementation 'androidx.test:runner:1.1.1' 67 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 68 | } 69 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def parse_KV_file(file, separator='=') 13 | file_abs_path = File.expand_path(file) 14 | if !File.exists? file_abs_path 15 | return []; 16 | end 17 | pods_ary = [] 18 | skip_line_start_symbols = ["#", "/"] 19 | File.foreach(file_abs_path) { |line| 20 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 21 | plugin = line.split(pattern=separator) 22 | if plugin.length == 2 23 | podname = plugin[0].strip() 24 | path = plugin[1].strip() 25 | podpath = File.expand_path("#{path}", file_abs_path) 26 | pods_ary.push({:name => podname, :path => podpath}); 27 | else 28 | puts "Invalid plugin specification: #{line}" 29 | end 30 | } 31 | return pods_ary 32 | end 33 | 34 | def pubspec_supports_macos(file) 35 | file_abs_path = File.expand_path(file) 36 | if !File.exists? file_abs_path 37 | return false; 38 | end 39 | File.foreach(file_abs_path) { |line| 40 | return true if line =~ /^\s*macos:/ 41 | } 42 | return false 43 | end 44 | 45 | target 'Runner' do 46 | use_frameworks! 47 | use_modular_headers! 48 | 49 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 50 | # referring to absolute paths on developers' machines. 51 | ephemeral_dir = File.join('Flutter', 'ephemeral') 52 | symlink_dir = File.join(ephemeral_dir, '.symlinks') 53 | symlink_plugins_dir = File.join(symlink_dir, 'plugins') 54 | system("rm -rf #{symlink_dir}") 55 | system("mkdir -p #{symlink_plugins_dir}") 56 | 57 | # Flutter Pods 58 | generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig')) 59 | if generated_xcconfig.empty? 60 | puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 61 | end 62 | generated_xcconfig.map { |p| 63 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 64 | symlink = File.join(symlink_dir, 'flutter') 65 | File.symlink(File.dirname(p[:path]), symlink) 66 | pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path])) 67 | end 68 | } 69 | 70 | # Plugin Pods 71 | plugin_pods = parse_KV_file('../.flutter-plugins') 72 | plugin_pods.map { |p| 73 | symlink = File.join(symlink_plugins_dir, p[:name]) 74 | File.symlink(p[:path], symlink) 75 | if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml')) 76 | pod p[:name], :path => File.join(symlink, 'macos') 77 | end 78 | } 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A new Flutter application. 3 | publish_to: none 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.12.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^1.0.0 26 | 27 | # Route 28 | airoute: 29 | path: ../ 30 | 31 | 32 | # WebView 33 | webview_flutter: ^4.10.0 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | 39 | 40 | # For information on the generic Dart part of this file, see the 41 | # following page: https://dart.dev/tools/pub/pubspec 42 | 43 | # The following section is specific to Flutter. 44 | flutter: 45 | 46 | # The following line ensures that the Material Icons font is 47 | # included with your application, so that you can use the icons in 48 | # the material Icons class. 49 | uses-material-design: true 50 | 51 | # To add assets to your application, add an assets section, like this: 52 | # assets: 53 | # - images/a_dot_burr.jpeg 54 | # - images/a_dot_ham.jpeg 55 | 56 | # An image asset can refer to one or more resolution-specific "variants", see 57 | # https://flutter.dev/assets-and-images/#resolution-aware. 58 | 59 | # For details regarding adding assets from package dependencies, see 60 | # https://flutter.dev/assets-and-images/#from-packages 61 | 62 | # To add custom fonts to your application, add a fonts section here, 63 | # in this "flutter" section. Each entry in this list should have a 64 | # "family" key with the font family name, and a "fonts" key with a 65 | # list giving the asset and other descriptors for the font. For 66 | # example: 67 | # fonts: 68 | # - family: Schyler 69 | # fonts: 70 | # - asset: fonts/Schyler-Regular.ttf 71 | # - asset: fonts/Schyler-Italic.ttf 72 | # style: italic 73 | # - family: Trajan Pro 74 | # fonts: 75 | # - asset: fonts/TrajanPro.ttf 76 | # - asset: fonts/TrajanPro_Bold.ttf 77 | # weight: 700 78 | # 79 | # For details regarding fonts from package dependencies, 80 | # see https://flutter.dev/custom-fonts/#from-packages 81 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | 84 | post_install do |installer| 85 | installer.pods_project.targets.each do |target| 86 | target.build_configurations.each do |config| 87 | config.build_settings['ENABLE_BITCODE'] = 'NO' 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:airoute/airoute.dart'; 2 | import 'package:example/page/launch_page.dart'; 3 | import 'package:example/page/second_page.dart'; 4 | import 'package:example/page/third_page.dart'; 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter/material.dart'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatefulWidget { 13 | @override 14 | State createState() { 15 | return AppState(); 16 | } 17 | } 18 | 19 | class AppState extends State { 20 | @override 21 | Widget build(BuildContext context) { 22 | return Airoute.createMaterialApp( 23 | home: LaunchPage(), 24 | routes: { 25 | "/LaunchPage": (_) => LaunchPage(), 26 | "/SecondPage": (_) => SecondPage(), 27 | "/ThirdPage": (_) => ThirdPage(), 28 | }, 29 | ); 30 | } 31 | } 32 | 33 | ///// 34 | ///// FlutterRoutePreview 35 | class FlutterRoutePreview extends StatefulWidget { 36 | @override 37 | State createState() { 38 | return _FlutterRoutePreviewState(); 39 | } 40 | } 41 | 42 | /// 43 | /// _FlutterRoutePreviewState 44 | class _FlutterRoutePreviewState extends State { 45 | @override 46 | Widget build(BuildContext context) { 47 | return Scaffold( 48 | body: Text("ddd"), 49 | ); 50 | } 51 | } 52 | //void main() async { 53 | // WidgetsFlutterBinding.ensureInitialized(); 54 | // Provider.debugCheckInvalidValueType = null; 55 | // 56 | // SystemChrome.setPreferredOrientations( 57 | // [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then( 58 | // (_) { 59 | // runApp( 60 | // MultiProvider( 61 | // providers: [ 62 | // Provider.value( 63 | // value: "this is test data", 64 | // ), 65 | // ], 66 | // child: OKToast( 67 | // child: StartupApplication(), 68 | // ), 69 | // ), 70 | // ); 71 | // }, 72 | // ); 73 | //} 74 | 75 | //void test() async { 76 | // WidgetsFlutterBinding.ensureInitialized(); 77 | // Provider.debugCheckInvalidValueType = null; 78 | // 79 | // SystemChrome.setPreferredOrientations( 80 | // [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]) 81 | // .then((_) {}); 82 | // runApp( 83 | // MultiProvider( 84 | // providers: [ 85 | // Provider.value( 86 | // value: "this is test data", 87 | // ), 88 | // ], 89 | // child: OKToast( 90 | // child: Airoute.createMaterialApp( 91 | // title: "Name", 92 | // theme: ThemeData( 93 | // fontFamily: 'IranSansLight', 94 | // primaryColor: Color(0xFF823A84), 95 | // accentColor: Color(0xFF823A84), 96 | // textTheme: TextTheme( 97 | // title: 98 | // TextStyle(fontFamily: 'IranSansLight', color: Colors.black), 99 | // ), 100 | // ), 101 | // home: LaunchPage(), 102 | // routes: { 103 | // "/LaunchPage": () => LaunchPage(), 104 | // "/SecondPage": () => SecondPage(), 105 | // }, 106 | // ), 107 | // ), 108 | // ), 109 | // ); 110 | //} 111 | // 112 | //class StartupApplication extends StatefulWidget { 113 | // @override 114 | // _StartupApplicationState createState() => _StartupApplicationState(); 115 | //} 116 | // 117 | //class _StartupApplicationState extends State { 118 | // @override 119 | // Widget build(BuildContext context) { 120 | // return Scaffold( 121 | // appBar: AppBar( 122 | // title: Text('Airoute'), 123 | // ), 124 | // body: Center( 125 | // child: Text("Welcome......!"), 126 | // ), 127 | // ); 128 | // } 129 | //} 130 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /example/lib/page/launch_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:airoute/airoute.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | /// 7 | /// LaunchPage 8 | class LaunchPage extends StatefulWidget with AirArgumentReceiver { 9 | dynamic _content = ""; 10 | @override 11 | void receive(AirArgument argument) { 12 | _content = argument.argument['content']; 13 | } 14 | 15 | @override 16 | State createState() { 17 | return _LaunchState(); 18 | } 19 | } 20 | 21 | /// _LaunchState 22 | class _LaunchState extends State { 23 | String _content = ""; 24 | @override 25 | Widget build(BuildContext context) { 26 | Size size = window.physicalSize; 27 | double width = size.width / window.devicePixelRatio; 28 | double height = size.height / window.devicePixelRatio; 29 | 30 | return Scaffold( 31 | appBar: AppBar( 32 | title: Text("LaunchPage"), 33 | ), 34 | body: SingleChildScrollView( 35 | child: Column( 36 | children: [ 37 | Text("Hello world ${widget._content}"), 38 | Container( 39 | width: width, 40 | height: height / 2, 41 | padding: EdgeInsets.only( 42 | left: 20, 43 | top: 20, 44 | right: 20, 45 | bottom: 20, 46 | ), 47 | child: Center( 48 | child: TextField( 49 | enabled: true, 50 | decoration: InputDecoration( 51 | icon: Text("参数"), 52 | prefixIcon: Icon(Icons.phone_android), 53 | ), 54 | onChanged: (String content) { 55 | _content = content; 56 | }, 57 | ), 58 | ), 59 | ), 60 | MaterialButton( 61 | onPressed: () { 62 | // Airoute.pushNamedWithAnimation( 63 | // routeName: "/SecondPage", 64 | // routePageAnimation: ( 65 | // BuildContext context, 66 | // Animation animation, 67 | // Animation secondaryAnimation, 68 | // Widget page, 69 | // ) { 70 | // return SlideTransition( 71 | // position: Tween( 72 | // begin: const Offset(1.0, 0.0), 73 | // end: const Offset(0.0, 0.0), 74 | // ).animate(animation), 75 | // child: page, 76 | // ); 77 | // }, 78 | // ); 79 | // Airoute.pushNamed( 80 | // routeName: "/SecondPage", 81 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 82 | // ); 83 | // Airoute.pushNamedWithAnimation( 84 | // routeName: "/SecondPage", 85 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 86 | // duration: Duration(milliseconds: 800), 87 | // routePageAnimation: ( 88 | // BuildContext context, 89 | // Animation animation, 90 | // Animation secondaryAnimation, 91 | // Widget page, 92 | // ) { 93 | // return FadeTransition( 94 | // opacity: CurvedAnimation( 95 | // parent: animation, curve: Curves.easeOut), 96 | // child: SlideTransition( 97 | // position: Tween( 98 | // begin: const Offset(1.0, 0.0), 99 | // end: const Offset(0.0, 0.0), 100 | // ).animate(animation), 101 | // child: page, 102 | // ), 103 | // ); 104 | // }, 105 | // ); 106 | // Airoute.pushNamedWithAnimation( 107 | // routeName: "/SecondPage", 108 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 109 | // routePageAnimation: AirouteTransition.Slide, 110 | // duration: Duration(milliseconds: 500), 111 | // ); 112 | // Airoute.pushNamedWithAnimation( 113 | // routeName: "/routeName", 114 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 115 | //// duration: Duration(milliseconds: 500), 116 | // routePageAnimation: _slide, 117 | // ); 118 | Airoute.pushNamedWithAnimation( 119 | routeName: "/SecondPage", 120 | argument: "$_content \n happy to see you", 121 | routePageAnimation: AirouteTransition.Slide, 122 | ); 123 | }, 124 | color: Theme.of(context).primaryColor, 125 | textColor: Colors.white, 126 | child: Text("跳转下一页"), 127 | ), 128 | ], 129 | ), 130 | ), 131 | ); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /README_DETAIL.md: -------------------------------------------------------------------------------- 1 | # Airoute 2 | 3 | ![totem](https://raw.githubusercontent.com/pdliuw/pdliuw.github.io/master/images/totem_four_logo.jpg) 4 | 5 | ----- 6 | 7 | |[English Document](https://github.com/pdliuw/airoute/blob/master/README-EN.md)|[中文文档](https://github.com/pdliuw/airoute)| 8 | |:-|:-| 9 | 10 | ## 我们的宗旨是:帮助开发者更加便利开发、切身体会编程之美! 11 | 12 | ### airoute: 13 | 14 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 15 | 16 | *1、支持无需context的路由管理, 17 | 18 | *2、支持‘非侵入式参数传递’的路由管理, 19 | 20 | *3、让你爱上路由管理的airoute 21 | 22 | [Airoute](https://github.com/pdliuw/airoute) 在[项目](https://github.com/flutter-app-sample/flutter_app_sample)中的实战应用[flutter sample](https://github.com/flutter-app-sample/flutter_app_sample) 23 | 24 | ## 效果图 25 | 26 | |iOS|Android| 27 | |:-|:-| 28 | |![airoute_ios](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_ios.gif)|![airoute_android](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_android.gif)| 29 | |:-|:-| 30 | 31 | |macOS|web| 32 | |:-|:-| 33 | |![airoute_macos](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_macos.gif)|![airoute_web](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_web.gif)| 34 | |:-|:-| 35 | 36 | ## 1.安装 37 | 38 | 使用当前包作为依赖库 39 | 40 | ### 1. 依赖此库 41 | 42 | 在文件 'pubspec.yaml' 中添加 43 | 44 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 45 | 46 | ``` 47 | 48 | dependencies: 49 | 50 | airoute: ^version 51 | 52 | ``` 53 | 54 | 或以这种方式添加 55 | 56 | ``` 57 | 58 | # Route package. 59 | airoute: 60 | git: 61 | url: https://github.com/pdliuw/airoute.git 62 | 63 | ``` 64 | 65 | ### 2. 安装此库 66 | 67 | 你可以通过下面的命令行来安装此库 68 | 69 | ``` 70 | 71 | $ flutter pub get 72 | 73 | 74 | ``` 75 | 76 | 你也可以通过项目开发工具通过可视化操作来执行上述步骤 77 | 78 | ### 3. 导入此库 79 | 80 | 现在,在你的Dart编辑代码中,你可以使用: 81 | 82 | ``` 83 | 84 | import 'package:airoute/airoute.dart'; 85 | 86 | ``` 87 | 88 | ## 2.使用 89 | 90 | ### 1.在你的项目入口'main.dart'中配置: 91 | 92 | Airoute 全局配置 93 | 94 | ``` 95 | 96 | void main() { 97 | runApp( 98 | /// 99 | /// 配置Airoute 100 | Airoute.createMaterialApp( 101 | home: LaunchPage(), 102 | routes: { 103 | "/LaunchPage": (_) => LaunchPage(), 104 | "/SecondPage": (_) => SecondPage(), 105 | }, 106 | ), 107 | ); 108 | } 109 | 110 | 111 | ``` 112 | 113 | 114 | ### 2.调用/应用 115 | 116 | *1、跳转新页面 117 | 118 | ``` 119 | 120 | Airoute.pushNamed(routeName: "/routeName"); 121 | 122 | ``` 123 | 124 | *2、关闭页面 125 | 126 | ``` 127 | 128 | Airoute.pop(); 129 | 130 | ``` 131 | 132 | *3、跳转新页面,并添加动画 133 | 134 | ``` 135 | 136 | Airoute.pushNamedWithAnimation( 137 | routeName: "/routeName", 138 | routePageAnimation: AirouteTransition.Slide); 139 | 140 | ``` 141 | 142 | 内置动画: 143 | 144 | 侧滑:AirouteTransition.Slide 145 | 渐变:AirouteTransition.Fade 146 | 缩放:AirouteTransition.Scale 147 | 旋转:AirouteTransition.Rotation 148 | 149 | *4、传递参数、接收参数 150 | 151 | 传递参数 152 | 153 | ``` 154 | 155 | Airoute.pushNamed( 156 | routeName: "/Page", 157 | argument: "遇见你,我很开心😄😄😄", 158 | ); 159 | 160 | ``` 161 | 162 | 传递number参数 163 | 164 | ``` 165 | 166 | Airoute.pushNamed( 167 | routeName: "/SecondPage", 168 | argument: 0, 169 | ); 170 | 171 | ``` 172 | 173 | 传递Map参数 174 | 175 | ``` 176 | Airoute.pushNamed( 177 | routeName: "/Page", 178 | argument: { 179 | "account":"this is accont", 180 | "password":"this is password ", 181 | }, 182 | ``` 183 | 184 | 传递Array参数 185 | 186 | ``` 187 | Airoute.pushNamed( 188 | routeName: "/Page", 189 | argument: [ 190 | "Air", 191 | "James", 192 | "Lucy", 193 | "Tom", 194 | ], 195 | ); 196 | 197 | ``` 198 | 199 | 200 | 接收参数 201 | 202 | ``` 203 | 204 | class Page extends StatefulWidget with AirArgumentReceiver { 205 | 206 | @override 207 | State createState() { 208 | return _PageState(); 209 | } 210 | 211 | @override 212 | void receive(AirArgument argument) { 213 | print("收到${argument.argument}参数了,我很开心😄😄😄"); 214 | } 215 | } 216 | 217 | 218 | ``` 219 | 220 | *5、路由跳转 221 | 222 | [![pub package](https://img.shields.io/pub/v/ai_awesome_message.svg)](https://pub.dev/packages/ai_awesome_message) 223 | 224 | ``` 225 | 226 | Airoute.push( 227 | route: AwesomeMessageRoute( 228 | awesomeMessage: AwesomeHelper.createAwesome( 229 | title: "title", message: "message"), 230 | theme: null, 231 | settings: RouteSettings(name: "/messageRouteName"), 232 | ), 233 | ); 234 | 235 | ``` 236 | 237 | *6、跳转新页面,并关闭当前页面 238 | 239 | ``` 240 | 241 | Airoute.pushReplacementNamed( 242 | routeName: "/routeName", 243 | ); 244 | 245 | ``` 246 | 247 | 248 | *7、跳转新页面,并关闭之前的所有页面 249 | 250 | ``` 251 | 252 | Airoute.pushNamedAndRemoveUntil( 253 | newRouteName: "/routeName", 254 | ); 255 | 256 | ``` 257 | 258 | *8、跳转新页面,并关闭除'untilRouteName'外的之前的所有页面 259 | 260 | ``` 261 | 262 | Airoute.pushNamedAndRemoveUntil( 263 | newRouteName: "/routeName", 264 | untilRouteName: "/untilRouteName", 265 | ); 266 | 267 | ``` 268 | 269 | 270 | 271 | ## LICENSE 272 | 273 | 274 | BSD 3-Clause License 275 | 276 | Copyright (c) 2020, pdliuw 277 | All rights reserved. 278 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | # Airoute 2 | 3 | ![totem](https://raw.githubusercontent.com/pdliuw/pdliuw.github.io/master/images/totem_four_logo.jpg) 4 | 5 | ----- 6 | 7 | |[English Document](https://github.com/pdliuw/airoute/blob/master/README-EN.md)|[中文文档](https://github.com/pdliuw/airoute)| 8 | |:-|:-| 9 | 10 | ## Our aim is to help developers make development more convenient and experience the beauty of programming! 11 | 12 | ### airoute: 13 | 14 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 15 | 16 | *1、Support routing management without context 17 | 18 | *2、Support 'non-intrusive parameter passing' routing management 19 | 20 | *3、Airoute that makes you fall in love with routing management 21 | 22 | [Airoute](https://github.com/pdliuw/airoute) in the[Project](https://github.com/flutter-app-sample/flutter_app_sample)Practical application[flutter sample](https://github.com/flutter-app-sample/flutter_app_sample) 23 | 24 | ## effect 25 | 26 | |iOS|Android| 27 | |:-|:-| 28 | |![airoute_ios](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_ios.gif)|![airoute_android](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_android.gif)| 29 | |:-|:-| 30 | 31 | |macOS|web| 32 | |:-|:-| 33 | |![airoute_macos](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_macos.gif)|![airoute_web](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_web.gif)| 34 | |:-|:-| 35 | 36 | 37 | ## 1.Installation 38 | 39 | Use the current package as a dependent library 40 | 41 | ### 1. Rely on this library 42 | 43 | Add in file 'pubspec.yaml' 44 | 45 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 46 | 47 | ``` 48 | 49 | dependencies: 50 | 51 | airoute: ^version 52 | 53 | ``` 54 | 55 | or 56 | 57 | ``` 58 | 59 | # Route package. 60 | airoute: 61 | git: 62 | url: https://github.com/pdliuw/airoute.git 63 | 64 | ``` 65 | 66 | ### 2. Install this library 67 | 68 | You can install this library via the command line below 69 | 70 | ``` 71 | 72 | $ flutter pub get 73 | 74 | 75 | ``` 76 | 77 | You can also perform the above steps through the visual operation through the project development tool 78 | 79 | 80 | ### 3. Import this library 81 | 82 | Now, in your Dart editing code, you can use: 83 | 84 | ``` 85 | 86 | import 'package:airoute/airoute.dart'; 87 | 88 | ``` 89 | 90 | ## 2.Usage 91 | 92 | ### 1.Configure in your project entry 'main.dart': 93 | 94 | Airoute Global configuration 95 | 96 | ``` 97 | 98 | void main() { 99 | runApp( 100 | /// 101 | /// Configuration Airoute 102 | Airoute.createMaterialApp( 103 | home: LaunchPage(), 104 | routes: { 105 | "/LaunchPage": (_) => LaunchPage(), 106 | "/SecondPage": (_) => SecondPage(), 107 | }, 108 | ), 109 | ); 110 | } 111 | 112 | 113 | ``` 114 | 115 | 116 | ### 2.Call / apply 117 | 118 | *1、Jump to new page 119 | 120 | ``` 121 | 122 | Airoute.pushNamed(routeName: "/routeName"); 123 | 124 | ``` 125 | 126 | *2、Close page 127 | 128 | ``` 129 | 130 | Airoute.pop(); 131 | 132 | ``` 133 | 134 | *3、Jump to new page and add animation 135 | 136 | ``` 137 | 138 | Airoute.pushNamedWithAnimation( 139 | routeName: "/routeName", 140 | routePageAnimation: AirouteTransition.Slide); 141 | 142 | ``` 143 | 144 | *4、Passing parameters, receiving parameters 145 | 146 | Passing parameters 147 | 148 | ``` 149 | 150 | Airoute.pushNamed( 151 | routeName: "/Page", 152 | argument: "I'm happy to meet you😄😄😄", 153 | ); 154 | 155 | ``` 156 | 157 | Passing number parameters 158 | 159 | ``` 160 | 161 | Airoute.pushNamed( 162 | routeName: "/SecondPage", 163 | argument: 0, 164 | ); 165 | 166 | ``` 167 | 168 | Passing Map parameters 169 | 170 | ``` 171 | Airoute.pushNamed( 172 | routeName: "/Page", 173 | argument: { 174 | "account":"this is accont", 175 | "password":"this is password ", 176 | }, 177 | ``` 178 | 179 | Passing Array parameters 180 | 181 | ``` 182 | Airoute.pushNamed( 183 | routeName: "/Page", 184 | argument: [ 185 | "Air", 186 | "James", 187 | "Lucy", 188 | "Tom", 189 | ], 190 | ); 191 | 192 | ``` 193 | 194 | Receiving parameters 195 | 196 | ``` 197 | 198 | class Page extends StatefulWidget with AirArgumentReceiver { 199 | 200 | @override 201 | State createState() { 202 | return _PageState(); 203 | } 204 | 205 | @override 206 | void receive(AirArgument argument) { 207 | print("Received${argument.argument}parameters,I am happy😄😄😄"); 208 | } 209 | } 210 | 211 | 212 | ``` 213 | 214 | 215 | *5、Push route 216 | 217 | 218 | [![pub package](https://img.shields.io/pub/v/ai_awesome_message.svg)](https://pub.dev/packages/ai_awesome_message) 219 | 220 | ``` 221 | 222 | Airoute.push( 223 | route: AwesomeMessageRoute( 224 | awesomeMessage: AwesomeHelper.createAwesome( 225 | title: "title", message: "message"), 226 | theme: null, 227 | settings: RouteSettings(name: "/messageRouteName"), 228 | ), 229 | ); 230 | 231 | ``` 232 | 233 | 234 | *6、More usage[click to see more](https://github.com/pdliuw/airoute/blob/master/README_DETAIL-EN.md) 235 | 236 | ### TODO 237 | 238 | * Support route interceptor. 239 | 240 | 241 | ## LICENSE 242 | 243 | BSD 3-Clause License 244 | 245 | Copyright (c) 2020, pdliuw 246 | All rights reserved. 247 | 248 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.18.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_test: 58 | dependency: "direct dev" 59 | description: flutter 60 | source: sdk 61 | version: "0.0.0" 62 | leak_tracker: 63 | dependency: transitive 64 | description: 65 | name: leak_tracker 66 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 67 | url: "https://pub.flutter-io.cn" 68 | source: hosted 69 | version: "10.0.5" 70 | leak_tracker_flutter_testing: 71 | dependency: transitive 72 | description: 73 | name: leak_tracker_flutter_testing 74 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 75 | url: "https://pub.flutter-io.cn" 76 | source: hosted 77 | version: "3.0.5" 78 | leak_tracker_testing: 79 | dependency: transitive 80 | description: 81 | name: leak_tracker_testing 82 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 83 | url: "https://pub.flutter-io.cn" 84 | source: hosted 85 | version: "3.0.1" 86 | matcher: 87 | dependency: transitive 88 | description: 89 | name: matcher 90 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 91 | url: "https://pub.flutter-io.cn" 92 | source: hosted 93 | version: "0.12.16+1" 94 | material_color_utilities: 95 | dependency: transitive 96 | description: 97 | name: material_color_utilities 98 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "0.11.1" 102 | meta: 103 | dependency: transitive 104 | description: 105 | name: meta 106 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 107 | url: "https://pub.flutter-io.cn" 108 | source: hosted 109 | version: "1.15.0" 110 | path: 111 | dependency: transitive 112 | description: 113 | name: path 114 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 115 | url: "https://pub.flutter-io.cn" 116 | source: hosted 117 | version: "1.9.0" 118 | sky_engine: 119 | dependency: transitive 120 | description: flutter 121 | source: sdk 122 | version: "0.0.99" 123 | source_span: 124 | dependency: transitive 125 | description: 126 | name: source_span 127 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "1.10.0" 131 | stack_trace: 132 | dependency: transitive 133 | description: 134 | name: stack_trace 135 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 136 | url: "https://pub.flutter-io.cn" 137 | source: hosted 138 | version: "1.11.1" 139 | stream_channel: 140 | dependency: transitive 141 | description: 142 | name: stream_channel 143 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 144 | url: "https://pub.flutter-io.cn" 145 | source: hosted 146 | version: "2.1.2" 147 | string_scanner: 148 | dependency: transitive 149 | description: 150 | name: string_scanner 151 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 152 | url: "https://pub.flutter-io.cn" 153 | source: hosted 154 | version: "1.2.0" 155 | term_glyph: 156 | dependency: transitive 157 | description: 158 | name: term_glyph 159 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 160 | url: "https://pub.flutter-io.cn" 161 | source: hosted 162 | version: "1.2.1" 163 | test_api: 164 | dependency: transitive 165 | description: 166 | name: test_api 167 | sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" 168 | url: "https://pub.flutter-io.cn" 169 | source: hosted 170 | version: "0.7.2" 171 | vector_math: 172 | dependency: transitive 173 | description: 174 | name: vector_math 175 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 176 | url: "https://pub.flutter-io.cn" 177 | source: hosted 178 | version: "2.1.4" 179 | vm_service: 180 | dependency: transitive 181 | description: 182 | name: vm_service 183 | sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" 184 | url: "https://pub.flutter-io.cn" 185 | source: hosted 186 | version: "14.2.5" 187 | sdks: 188 | dart: ">=3.3.0 <4.0.0" 189 | flutter: ">=3.18.0-18.0.pre.54" 190 | -------------------------------------------------------------------------------- /README_DETAIL-EN.md: -------------------------------------------------------------------------------- 1 | # Airoute 2 | 3 | ![totem](https://raw.githubusercontent.com/pdliuw/pdliuw.github.io/master/images/totem_four_logo.jpg) 4 | 5 | ----- 6 | 7 | |[English Document](https://github.com/pdliuw/airoute/blob/master/README-EN.md)|[中文文档](https://github.com/pdliuw/airoute)| 8 | |:-|:-| 9 | 10 | ## Our aim is to help developers make development more convenient and experience the beauty of programming! 11 | 12 | ### airoute: 13 | 14 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 15 | 16 | *1、Support routing management without context 17 | 18 | *2、Support 'non-intrusive parameter passing' routing management 19 | 20 | *3、Airoute that makes you fall in love with routing management 21 | 22 | [Airoute](https://github.com/pdliuw/airoute) in the[Project](https://github.com/flutter-app-sample/flutter_app_sample)Practical application[flutter sample](https://github.com/flutter-app-sample/flutter_app_sample) 23 | 24 | ## effect 25 | 26 | |iOS|Android| 27 | |:-|:-| 28 | |![airoute_ios](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_ios.gif)|![airoute_android](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_android.gif)| 29 | |:-|:-| 30 | 31 | |macOS|web| 32 | |:-|:-| 33 | |![airoute_macos](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_macos.gif)|![airoute_web](https://github.com/pdliuw/airoute/blob/master/example/raw/airoute_render_web.gif)| 34 | |:-|:-| 35 | 36 | 37 | ## 1.Installation 38 | 39 | Use the current package as a dependent library 40 | 41 | ### 1. Rely on this library 42 | 43 | Add in file 'pubspec.yaml' 44 | 45 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 46 | 47 | ``` 48 | 49 | dependencies: 50 | 51 | airoute: ^version 52 | 53 | ``` 54 | 55 | 56 | or 57 | 58 | ``` 59 | 60 | # Route package. 61 | airoute: 62 | git: 63 | url: https://github.com/pdliuw/airoute.git 64 | 65 | ``` 66 | 67 | ### 2. Install this library 68 | 69 | You can install this library via the command line below 70 | 71 | ``` 72 | 73 | $ flutter pub get 74 | 75 | 76 | ``` 77 | 78 | You can also perform the above steps through the visual operation through the project development tool 79 | 80 | 81 | ### 3. Import this library 82 | 83 | Now, in your Dart editing code, you can use: 84 | 85 | ``` 86 | 87 | import 'package:airoute/airoute.dart'; 88 | 89 | ``` 90 | 91 | ## 2.Usage 92 | 93 | ### 1.Configure in your project entry 'main.dart': 94 | 95 | Airoute Global configuration 96 | 97 | ``` 98 | 99 | void main() { 100 | runApp( 101 | /// 102 | /// Configuration Airoute 103 | Airoute.createMaterialApp( 104 | home: LaunchPage(), 105 | routes: { 106 | "/LaunchPage": (_) => LaunchPage(), 107 | "/SecondPage": (_) => SecondPage(), 108 | }, 109 | ), 110 | ); 111 | } 112 | 113 | 114 | ``` 115 | 116 | 117 | ### 2.Call / apply 118 | 119 | *1、Jump to new page 120 | 121 | ``` 122 | 123 | Airoute.pushNamed(routeName: "/routeName"); 124 | 125 | ``` 126 | 127 | *2、Close page 128 | 129 | ``` 130 | 131 | Airoute.pop(); 132 | 133 | ``` 134 | 135 | *3、Jump to new page and add animation 136 | 137 | ``` 138 | 139 | Airoute.pushNamedWithAnimation( 140 | routeName: "/routeName", 141 | routePageAnimation: AirouteTransition.Slide); 142 | 143 | ``` 144 | 145 | *4、Passing parameters, receiving parameters 146 | 147 | Passing parameters 148 | 149 | ``` 150 | 151 | Airoute.pushNamed( 152 | routeName: "/Page", 153 | argument: "I'm happy to meet you😄😄😄", 154 | ); 155 | 156 | ``` 157 | 158 | Passing number parameters 159 | 160 | ``` 161 | 162 | Airoute.pushNamed( 163 | routeName: "/SecondPage", 164 | argument: 0, 165 | ); 166 | 167 | ``` 168 | 169 | Passing Map parameters 170 | 171 | ``` 172 | Airoute.pushNamed( 173 | routeName: "/Page", 174 | argument: { 175 | "account":"this is accont", 176 | "password":"this is password ", 177 | }, 178 | ``` 179 | 180 | Passing Array parameters 181 | 182 | ``` 183 | Airoute.pushNamed( 184 | routeName: "/Page", 185 | argument: [ 186 | "Air", 187 | "James", 188 | "Lucy", 189 | "Tom", 190 | ], 191 | ); 192 | 193 | ``` 194 | 195 | 196 | Receiving parameters 197 | 198 | ``` 199 | 200 | class Page extends StatefulWidget with AirArgumentReceiver { 201 | 202 | @override 203 | State createState() { 204 | return _PageState(); 205 | } 206 | 207 | @override 208 | void receive(AirArgument argument) { 209 | print("Received${argument.argument}parameters,I am happy😄😄😄"); 210 | } 211 | } 212 | 213 | 214 | ``` 215 | 216 | 217 | *5、Push route 218 | 219 | [![pub package](https://img.shields.io/pub/v/ai_awesome_message.svg)](https://pub.dev/packages/ai_awesome_message) 220 | 221 | ``` 222 | 223 | Airoute.push( 224 | route: AwesomeMessageRoute( 225 | awesomeMessage: AwesomeHelper.createAwesome( 226 | title: "title", message: "message"), 227 | theme: null, 228 | settings: RouteSettings(name: "/messageRouteName"), 229 | ), 230 | ); 231 | 232 | ``` 233 | 234 | 235 | 236 | *6、Jump to a new page and close the current page 237 | 238 | ``` 239 | 240 | Airoute.pushReplacementNamed( 241 | routeName: "/routeName", 242 | ); 243 | 244 | ``` 245 | 246 | 247 | *7、Jump to new page and close all previous pages 248 | 249 | ``` 250 | 251 | Airoute.pushNamedAndRemoveUntil( 252 | newRouteName: "/routeName", 253 | ); 254 | 255 | ``` 256 | 257 | *8、Jump to new page and close all previous pages except 'untilRouteName' 258 | 259 | ``` 260 | 261 | Airoute.pushNamedAndRemoveUntil( 262 | newRouteName: "/routeName", 263 | untilRouteName: "/untilRouteName", 264 | ); 265 | 266 | ``` 267 | 268 | 269 | 270 | ## LICENSE 271 | 272 | BSD 3-Clause License 273 | 274 | Copyright (c) 2020, pdliuw 275 | All rights reserved. 276 | 277 | 278 | -------------------------------------------------------------------------------- /lib/route/navigator_manager.dart: -------------------------------------------------------------------------------- 1 | part of airoute; 2 | 3 | /// 4 | /// NavigatorManager 5 | class NavigatorManager { 6 | /// 7 | /// Route config map. 8 | static Map _route = {}; 9 | 10 | /// 11 | /// NavigatorManager. 12 | static NavigatorManager? _singleInstance; 13 | 14 | /// 15 | /// Navigator. 16 | // ignore: non_constant_identifier_names 17 | static final GlobalKey GLOBAL_KEY = GlobalKey(); 18 | 19 | /// 20 | /// NavigatorManager. 21 | NavigatorManager._(); 22 | 23 | /// 24 | /// Instance. 25 | static NavigatorManager? getInstance() { 26 | if (_singleInstance == null) { 27 | _singleInstance = NavigatorManager._(); 28 | } 29 | return _singleInstance; 30 | } 31 | 32 | /// 33 | /// Initialize routes[_route]. 34 | static Map initializeRoutes({ 35 | required Map routes, 36 | }) { 37 | _route = routes; 38 | return _route; 39 | } 40 | 41 | /// 42 | /// Initialize generate route. 43 | static Route initializeGenerateRoute(RouteSettings routeSettings) { 44 | bool isInitialRoute = false; 45 | String routeName = routeSettings.name!; 46 | dynamic arguments = routeSettings.arguments; 47 | //Builder. 48 | WidgetBuilder widgetBuilder = _route[routeName]!; 49 | 50 | Widget widget = widgetBuilder(navigator!.context); 51 | 52 | if (widget is AirArgumentReceiver) { 53 | AirArgumentReceiver argumentReceiver = widget as AirArgumentReceiver; 54 | argumentReceiver.receive( 55 | AirArgument( 56 | routeName: routeName, 57 | argument: arguments, 58 | isInitialRoute: isInitialRoute, 59 | ), 60 | ); 61 | } 62 | 63 | return CupertinoPageRoute( 64 | builder: (_) { 65 | return widget; 66 | }, 67 | settings: routeSettings, 68 | ); 69 | } 70 | 71 | /// 72 | /// Context. 73 | BuildContext context({ 74 | String? routeName, 75 | }) { 76 | return navigator!.context; 77 | } 78 | 79 | /// 80 | /// Replace. 81 | pushReplacementNamed({ 82 | required String routeName, 83 | dynamic argument, 84 | }) { 85 | return navigator?.pushReplacementNamed( 86 | routeName, 87 | arguments: argument, 88 | ); 89 | } 90 | 91 | /// 92 | /// Push. 93 | pushNamed({ 94 | required String routeName, 95 | dynamic argument, 96 | }) { 97 | RouteSettings routeSettings = RouteSettings(name: routeName, arguments: argument); 98 | 99 | WidgetBuilder widgetBuilder = _route[routeSettings.name]!; 100 | Widget widget = widgetBuilder(navigator!.context); 101 | 102 | if (widget is AirArgumentReceiver) { 103 | AirArgumentReceiver argumentReceiver = widget as AirArgumentReceiver; 104 | argumentReceiver.receive( 105 | AirArgument( 106 | routeName: routeSettings.name!, 107 | argument: routeSettings.arguments, 108 | isInitialRoute: false, 109 | ), 110 | ); 111 | return navigator?.push( 112 | CupertinoPageRoute( 113 | builder: (context) { 114 | return widget; 115 | }, 116 | settings: routeSettings, 117 | ), 118 | ); 119 | } 120 | return navigator?.pushNamed( 121 | routeName, 122 | arguments: argument, 123 | ); 124 | } 125 | 126 | /// 127 | /// push 128 | Future push({ 129 | required Route route, 130 | }) { 131 | return navigator!.push(route); 132 | } 133 | 134 | /// 135 | /// Push with animation. 136 | pushNamedWithAnimation({ 137 | required String routeName, 138 | dynamic argument, 139 | RoutePageAnimation routePageAnimation = AirouteTransition.Slide, 140 | Duration duration = const Duration(milliseconds: 500), 141 | }) { 142 | return navigator?.push( 143 | PageRouteBuilder( 144 | transitionDuration: duration, 145 | settings: RouteSettings( 146 | name: routeName, 147 | arguments: argument, 148 | ), 149 | pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) { 150 | //WidgetBuilder 151 | WidgetBuilder widgetBuilder = _route[routeName]!; 152 | Widget? widget = widgetBuilder(navigator!.context); 153 | if (widget is AirArgumentReceiver) { 154 | AirArgumentReceiver argumentReceiver = widget as AirArgumentReceiver; 155 | argumentReceiver.receive( 156 | AirArgument( 157 | argument: argument, 158 | routeName: routeName, 159 | ), 160 | ); 161 | } 162 | //Route page animation 163 | return routePageAnimation( 164 | context, 165 | animation, 166 | secondaryAnimation, 167 | widget, 168 | ); 169 | }, 170 | ), 171 | ); 172 | } 173 | 174 | /// 175 | /// Pop. 176 | pop({ 177 | dynamic result, 178 | }) { 179 | if (navigator?.canPop() ?? false) { 180 | navigator?.pop(result); 181 | } 182 | } 183 | 184 | /// 185 | /// PopUntil[untilRouteName]. 186 | popUntil({ 187 | required String? untilRouteName, 188 | }) { 189 | bool isPopAll = untilRouteName == null ? true : false; 190 | if (isPopAll) { 191 | pop(); 192 | } else { 193 | navigator?.popUntil(ModalRoute.withName('$untilRouteName')); 194 | } 195 | } 196 | 197 | /// 198 | /// Push[newRouteName]and remove until [untilRouteName]. 199 | pushNamedAndRemoveUntil({ 200 | required String newRouteName, 201 | required String? untilRouteName, 202 | dynamic argument, 203 | RoutePageAnimation routePageAnimation = AirouteTransition.Slide, 204 | }) { 205 | bool isRemoveAll = untilRouteName == null ? true : false; 206 | 207 | if (isRemoveAll) { 208 | //remove all. 209 | return navigator?.pushNamedAndRemoveUntil( 210 | newRouteName, 211 | (Route route) { 212 | return false; 213 | }, 214 | arguments: argument, 215 | ); 216 | } else { 217 | //not remove all. 218 | return navigator?.pushNamedAndRemoveUntil( 219 | newRouteName, 220 | ModalRoute.withName('$untilRouteName'), 221 | arguments: argument, 222 | ); 223 | } 224 | } 225 | 226 | /// 227 | /// navigatorKey. 228 | static NavigatorState? get navigator { 229 | return GLOBAL_KEY.currentState; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /lib/route/app.dart: -------------------------------------------------------------------------------- 1 | part of airoute; 2 | 3 | typedef AirouteBuilder = Widget Function(); 4 | 5 | /// 6 | /// AirApp 7 | class AirouteApp { 8 | /// 9 | /// Create MaterialApp 10 | static MaterialApp createMaterialApp({ 11 | Key? key, 12 | GlobalKey? navigatorKey, 13 | Widget? home, 14 | Map routes = const {}, 15 | String? initialRoute, 16 | RouteFactory? onGenerateRoute, 17 | RouteFactory? onUnknownRoute, 18 | List navigatorObservers = const [], 19 | TransitionBuilder? builder, 20 | String title = '', 21 | GenerateAppTitle? onGenerateTitle, 22 | Color? color, 23 | ThemeData? theme, 24 | ThemeData? darkTheme, 25 | ThemeMode? themeMode = ThemeMode.system, 26 | Locale? locale, 27 | Iterable>? localizationsDelegates, 28 | LocaleListResolutionCallback? localeListResolutionCallback, 29 | LocaleResolutionCallback? localeResolutionCallback, 30 | Iterable supportedLocales = const [Locale('en', 'US')], 31 | bool debugShowMaterialGrid = false, 32 | bool showPerformanceOverlay = false, 33 | bool checkerboardRasterCacheImages = false, 34 | bool checkerboardOffscreenLayers = false, 35 | bool showSemanticsDebugger = false, 36 | bool debugShowCheckedModeBanner = true, 37 | Map? shortcuts, 38 | Map>? actions, 39 | }) { 40 | NavigatorManager.initializeRoutes(routes: routes); 41 | return MaterialApp( 42 | key: key, 43 | navigatorKey: NavigatorManager.GLOBAL_KEY, 44 | home: home, 45 | initialRoute: initialRoute, 46 | routes: routes, 47 | onGenerateRoute: RouteManager.initializeGenerateRoute, 48 | onUnknownRoute: onUnknownRoute, 49 | navigatorObservers: navigatorObservers, 50 | builder: builder, 51 | title: title, 52 | onGenerateTitle: onGenerateTitle, 53 | color: color, 54 | theme: theme, 55 | darkTheme: darkTheme, 56 | themeMode: themeMode, 57 | actions: actions, 58 | locale: locale, 59 | localizationsDelegates: localizationsDelegates, 60 | localeListResolutionCallback: localeListResolutionCallback, 61 | localeResolutionCallback: localeResolutionCallback, 62 | supportedLocales: supportedLocales, 63 | debugShowMaterialGrid: debugShowMaterialGrid, 64 | showPerformanceOverlay: showPerformanceOverlay, 65 | checkerboardRasterCacheImages: checkerboardRasterCacheImages, 66 | checkerboardOffscreenLayers: checkerboardOffscreenLayers, 67 | showSemanticsDebugger: showSemanticsDebugger, 68 | debugShowCheckedModeBanner: debugShowCheckedModeBanner, 69 | ); 70 | } 71 | 72 | /// 73 | /// Create CupertinoApp 74 | static CupertinoApp createCupertinoApp({ 75 | Key? key, 76 | GlobalKey? navigatorKey, 77 | Widget? home, 78 | Map routes = const {}, 79 | String? initialRoute, 80 | RouteFactory? onGenerateRoute, 81 | RouteFactory? onUnknownRoute, 82 | List navigatorObservers = const [], 83 | TransitionBuilder? builder, 84 | String title = '', 85 | GenerateAppTitle? onGenerateTitle, 86 | Color? color, 87 | CupertinoThemeData? theme, 88 | CupertinoThemeData? darkTheme, 89 | ThemeMode? themeMode = ThemeMode.system, 90 | Locale? locale, 91 | Iterable>? localizationsDelegates, 92 | LocaleListResolutionCallback? localeListResolutionCallback, 93 | LocaleResolutionCallback? localeResolutionCallback, 94 | Iterable supportedLocales = const [Locale('en', 'US')], 95 | bool debugShowMaterialGrid = false, 96 | bool showPerformanceOverlay = false, 97 | bool checkerboardRasterCacheImages = false, 98 | bool checkerboardOffscreenLayers = false, 99 | bool showSemanticsDebugger = false, 100 | bool debugShowCheckedModeBanner = true, 101 | Map? shortcuts, 102 | Map>? actions, 103 | }) { 104 | NavigatorManager.initializeRoutes(routes: routes); 105 | return CupertinoApp( 106 | key: key, 107 | navigatorKey: NavigatorManager.GLOBAL_KEY, 108 | home: home, 109 | initialRoute: initialRoute, 110 | routes: routes, 111 | onGenerateRoute: RouteManager.initializeGenerateRoute, 112 | onUnknownRoute: onUnknownRoute, 113 | navigatorObservers: navigatorObservers, 114 | builder: builder, 115 | title: title, 116 | onGenerateTitle: onGenerateTitle, 117 | color: color, 118 | theme: theme, 119 | locale: locale, 120 | localizationsDelegates: localizationsDelegates, 121 | localeListResolutionCallback: localeListResolutionCallback, 122 | localeResolutionCallback: localeResolutionCallback, 123 | supportedLocales: supportedLocales, 124 | showPerformanceOverlay: showPerformanceOverlay, 125 | checkerboardRasterCacheImages: checkerboardRasterCacheImages, 126 | checkerboardOffscreenLayers: checkerboardOffscreenLayers, 127 | showSemanticsDebugger: showSemanticsDebugger, 128 | debugShowCheckedModeBanner: debugShowCheckedModeBanner, 129 | ); 130 | } 131 | 132 | /// 133 | /// Create CupertinoApp 134 | static WidgetsApp createWidgetsApp({ 135 | Key? key, 136 | GlobalKey? navigatorKey, 137 | Widget? home, 138 | Map routes = const {}, 139 | String? initialRoute, 140 | RouteFactory? onGenerateRoute, 141 | RouteFactory? onUnknownRoute, 142 | List navigatorObservers = const [], 143 | TransitionBuilder? builder, 144 | String title = '', 145 | GenerateAppTitle? onGenerateTitle, 146 | required Color color, 147 | CupertinoThemeData? theme, 148 | CupertinoThemeData? darkTheme, 149 | ThemeMode? themeMode = ThemeMode.system, 150 | Locale? locale, 151 | Iterable>? localizationsDelegates, 152 | LocaleListResolutionCallback? localeListResolutionCallback, 153 | LocaleResolutionCallback? localeResolutionCallback, 154 | Iterable supportedLocales = const [Locale('en', 'US')], 155 | bool debugShowMaterialGrid = false, 156 | bool showPerformanceOverlay = false, 157 | bool checkerboardRasterCacheImages = false, 158 | bool checkerboardOffscreenLayers = false, 159 | bool showSemanticsDebugger = false, 160 | bool debugShowCheckedModeBanner = true, 161 | Map? shortcuts, 162 | Map>? actions, 163 | }) { 164 | NavigatorManager.initializeRoutes(routes: routes); 165 | return WidgetsApp( 166 | key: key, 167 | navigatorKey: NavigatorManager.GLOBAL_KEY, 168 | home: home, 169 | initialRoute: initialRoute, 170 | routes: routes, 171 | onGenerateRoute: RouteManager.initializeGenerateRoute, 172 | onUnknownRoute: onUnknownRoute, 173 | navigatorObservers: navigatorObservers, 174 | builder: builder, 175 | title: title, 176 | onGenerateTitle: onGenerateTitle, 177 | color: color, 178 | locale: locale, 179 | localizationsDelegates: localizationsDelegates, 180 | localeListResolutionCallback: localeListResolutionCallback, 181 | localeResolutionCallback: localeResolutionCallback, 182 | supportedLocales: supportedLocales, 183 | showPerformanceOverlay: showPerformanceOverlay, 184 | showSemanticsDebugger: showSemanticsDebugger, 185 | debugShowCheckedModeBanner: debugShowCheckedModeBanner, 186 | ); 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /example/Fix.md: -------------------------------------------------------------------------------- 1 | ## 修复若干! 2 | 3 | ![totem](https://raw.githubusercontent.com/pdliuw/pdliuw.github.io/master/images/totem_four_logo.jpg) 4 | 5 | ----- 6 | 7 | |[English Document](https://github.com/pdliuw/airoute/blob/master/example/Fix_EN.md)|[中文文档](https://github.com/pdliuw/airoute/blob/master/example/Fix.md)| 8 | |:-|:-| 9 | 10 | ### 1、observer.navigator == null 11 | 12 | #### 1、代码: 13 | 14 | ``` 15 | 16 | void main() async { 17 | WidgetsFlutterBinding.ensureInitialized(); 18 | Provider.debugCheckInvalidValueType = null; 19 | 20 | SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) { 21 | runApp(MultiProvider(providers: providers, child: OKToast(child: StartupApplication()))); 22 | }); 23 | } 24 | } 25 | 26 | class StartupApplication extends StatefulWidget { 27 | @override 28 | _StartupApplicationState createState() => _StartupApplicationState(); 29 | } 30 | 31 | class _StartupApplicationState extends State { 32 | @override 33 | Widget build(BuildContext context) { 34 | return Airoute.createMaterialApp( 35 | title: Fa.appName, 36 | theme: ThemeData( 37 | fontFamily: 'IranSansLight', 38 | primaryColor: Color(0xFF823A84), 39 | accentColor: Color(0xFF823A84), 40 | textTheme: TextTheme(title: TextStyle(fontFamily: 'IranSansLight', color: Colors.black)), 41 | ), 42 | home: Directionality(), 43 | routes: { 44 | "/home": () => Home(), 45 | "/lesson": () => LessonsPage(), 46 | "/play": () => LessonDetail(), 47 | "/certificateOfDisclaimer": () => LessonsCertificateOfDisclaimer(), 48 | "/tickets": () => Tickets(), 49 | "/keywords": () => Keywords(), 50 | "/faq": () => Faq(), 51 | "/aboutUs": () => AboutUs(), 52 | "/contactUs": () => ContactUs(), 53 | "/serviceRole": () => ServiceRole(), 54 | "/showLessonParts": () => ShowLessonParts(), 55 | "/main_route": () => MainRoute(), 56 | "/pageConceptsInformation": () => ShowPageConceptsInformation(), 57 | "/pageLessonsDescription": () => ShowPageLessonsDescription(), 58 | "/profileCode": () => ProfileCode(), 59 | "/market": () => Market(), 60 | "/results": () => Results(), 61 | "/documents": () => Documents(), 62 | "/lessonDescription": () => LessonDescription(), 63 | "/monthDescription": () => MonthDescription(), 64 | "/readMeLesson": () => ReadmeLesson(), 65 | "/logout": () => Logout(), 66 | "/showDocumentContent": () => ShowDocumentContent(), 67 | }, 68 | ); 69 | } 70 | } 71 | 72 | ``` 73 | 74 | #### 2、Error: 75 | 76 | ``` 77 | 78 | ════════ Exception caught by widgets library ═════════ 79 | The following assertion was thrown building Builder: 80 | 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 1578 pos 16: 'observer.navigator == null': is not true. 81 | 82 | 83 | Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. 84 | In either case, please report this assertion by filing a bug on GitHub: 85 | https://github.com/flutter/flutter/issues/new?template=BUG.md 86 | 87 | The relevant error-causing widget was: 88 | MaterialApp file:///C:/Users/mahdi/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/airoute-0.1.4/lib/route/app.dart:45:12 89 | When the exception was thrown, this was the stack: 90 | #2 NavigatorState.didUpdateWidget (package:flutter/src/widgets/navigator.dart:1578:16) 91 | #3 StatefulElement.update (package:flutter/src/widgets/framework.dart:4396:58) 92 | #4 Element.updateChild (package:flutter/src/widgets/framework.dart:2977:15) 93 | #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4243:16) 94 | #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3947:5) 95 | 96 | ``` 97 | 98 | #### 3、修复问题 99 | 100 | 问题复现: 101 | 102 | ``` 103 | 104 | 105 | dependencies: 106 | flutter: 107 | sdk: flutter 108 | 109 | # The following adds the Cupertino Icons font to your application. 110 | # Use with the CupertinoIcons class for iOS style icons. 111 | cupertino_icons: ^0.1.2 112 | 113 | # Route 114 | airoute: ^0.1.6 115 | provider: ^4.0.1 116 | oktoast: ^2.3.0 117 | 118 | 119 | 120 | ``` 121 | 122 | ``` 123 | void main() async { 124 | WidgetsFlutterBinding.ensureInitialized(); 125 | Provider.debugCheckInvalidValueType = null; 126 | 127 | SystemChrome.setPreferredOrientations( 128 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) { 129 | runApp(MultiProvider(providers: [ 130 | Provider.value( 131 | value: "this is test data", 132 | ), 133 | ], child: OKToast(child: StartupApplication()))); 134 | }); 135 | } 136 | 137 | ``` 138 | 139 | ``` 140 | 141 | 142 | class StartupApplication extends StatefulWidget { 143 | @override 144 | _StartupApplicationState createState() => _StartupApplicationState(); 145 | } 146 | 147 | class _StartupApplicationState extends State { 148 | @override 149 | Widget build(BuildContext context) { 150 | return Airoute.createMaterialApp( 151 | title: "Name", 152 | theme: ThemeData( 153 | fontFamily: 'IranSansLight', 154 | primaryColor: Color(0xFF823A84), 155 | accentColor: Color(0xFF823A84), 156 | textTheme: TextTheme( 157 | title: TextStyle(fontFamily: 'IranSansLight', color: Colors.black), 158 | ), 159 | ), 160 | home: LaunchPage(), 161 | routes: { 162 | "/LaunchPage": () => LaunchPage(), 163 | "/SecondPage": () => SecondPage(), 164 | }, 165 | ); 166 | } 167 | } 168 | 169 | 170 | ``` 171 | 172 | 解决之道: 173 | 174 | ``` 175 | 176 | 177 | void main() async { 178 | WidgetsFlutterBinding.ensureInitialized(); 179 | Provider.debugCheckInvalidValueType = null; 180 | 181 | SystemChrome.setPreferredOrientations( 182 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]) 183 | .then((_) {}); 184 | runApp( 185 | MultiProvider( 186 | providers: [ 187 | Provider.value( 188 | value: "this is test data", 189 | ), 190 | ], 191 | child: OKToast( 192 | child: Airoute.createMaterialApp( 193 | title: "Name", 194 | theme: ThemeData( 195 | fontFamily: 'IranSansLight', 196 | primaryColor: Color(0xFF823A84), 197 | accentColor: Color(0xFF823A84), 198 | textTheme: TextTheme( 199 | title: 200 | TextStyle(fontFamily: 'IranSansLight', color: Colors.black), 201 | ), 202 | ), 203 | home: StartupApplication(), 204 | routes: { 205 | "/LaunchPage": () => LaunchPage(), 206 | "/SecondPage": () => SecondPage(), 207 | }, 208 | ), 209 | ), 210 | ), 211 | ); 212 | } 213 | 214 | class StartupApplication extends StatefulWidget { 215 | @override 216 | _StartupApplicationState createState() => _StartupApplicationState(); 217 | } 218 | 219 | class _StartupApplicationState extends State { 220 | @override 221 | Widget build(BuildContext context) { 222 | return Scaffold( 223 | appBar: AppBar( 224 | title: Text('Airoute'), 225 | ), 226 | body: Center( 227 | child: Text("Welcome......!"), 228 | ), 229 | ); 230 | } 231 | } 232 | 233 | 234 | ``` 235 | 236 | 237 | ----- -------------------------------------------------------------------------------- /example/Fix_EN.md: -------------------------------------------------------------------------------- 1 | ## Fix something! 2 | 3 | 4 | ![totem](https://raw.githubusercontent.com/pdliuw/pdliuw.github.io/master/images/totem_four_logo.jpg) 5 | 6 | ----- 7 | 8 | |[English Document](https://github.com/pdliuw/airoute/blob/master/example/Fix_EN.md)|[中文文档](https://github.com/pdliuw/airoute/blob/master/example/Fix.md)| 9 | |:-|:-| 10 | 11 | 12 | ### 1、observer.navigator == null 13 | 14 | #### 1、Code: 15 | 16 | ``` 17 | 18 | void main() async { 19 | WidgetsFlutterBinding.ensureInitialized(); 20 | Provider.debugCheckInvalidValueType = null; 21 | 22 | SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) { 23 | runApp(MultiProvider(providers: providers, child: OKToast(child: StartupApplication()))); 24 | }); 25 | } 26 | } 27 | 28 | class StartupApplication extends StatefulWidget { 29 | @override 30 | _StartupApplicationState createState() => _StartupApplicationState(); 31 | } 32 | 33 | class _StartupApplicationState extends State { 34 | @override 35 | Widget build(BuildContext context) { 36 | return Airoute.createMaterialApp( 37 | title: Fa.appName, 38 | theme: ThemeData( 39 | fontFamily: 'IranSansLight', 40 | primaryColor: Color(0xFF823A84), 41 | accentColor: Color(0xFF823A84), 42 | textTheme: TextTheme(title: TextStyle(fontFamily: 'IranSansLight', color: Colors.black)), 43 | ), 44 | home: Directionality(), 45 | routes: { 46 | "/home": () => Home(), 47 | "/lesson": () => LessonsPage(), 48 | "/play": () => LessonDetail(), 49 | "/certificateOfDisclaimer": () => LessonsCertificateOfDisclaimer(), 50 | "/tickets": () => Tickets(), 51 | "/keywords": () => Keywords(), 52 | "/faq": () => Faq(), 53 | "/aboutUs": () => AboutUs(), 54 | "/contactUs": () => ContactUs(), 55 | "/serviceRole": () => ServiceRole(), 56 | "/showLessonParts": () => ShowLessonParts(), 57 | "/main_route": () => MainRoute(), 58 | "/pageConceptsInformation": () => ShowPageConceptsInformation(), 59 | "/pageLessonsDescription": () => ShowPageLessonsDescription(), 60 | "/profileCode": () => ProfileCode(), 61 | "/market": () => Market(), 62 | "/results": () => Results(), 63 | "/documents": () => Documents(), 64 | "/lessonDescription": () => LessonDescription(), 65 | "/monthDescription": () => MonthDescription(), 66 | "/readMeLesson": () => ReadmeLesson(), 67 | "/logout": () => Logout(), 68 | "/showDocumentContent": () => ShowDocumentContent(), 69 | }, 70 | ); 71 | } 72 | } 73 | 74 | ``` 75 | 76 | #### 2、Error: 77 | 78 | ``` 79 | 80 | ════════ Exception caught by widgets library ═════════ 81 | The following assertion was thrown building Builder: 82 | 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 1578 pos 16: 'observer.navigator == null': is not true. 83 | 84 | 85 | Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. 86 | In either case, please report this assertion by filing a bug on GitHub: 87 | https://github.com/flutter/flutter/issues/new?template=BUG.md 88 | 89 | The relevant error-causing widget was: 90 | MaterialApp file:///C:/Users/mahdi/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/airoute-0.1.4/lib/route/app.dart:45:12 91 | When the exception was thrown, this was the stack: 92 | #2 NavigatorState.didUpdateWidget (package:flutter/src/widgets/navigator.dart:1578:16) 93 | #3 StatefulElement.update (package:flutter/src/widgets/framework.dart:4396:58) 94 | #4 Element.updateChild (package:flutter/src/widgets/framework.dart:2977:15) 95 | #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4243:16) 96 | #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3947:5) 97 | 98 | ``` 99 | 100 | #### 3、Solution or Answer 101 | 102 | Before solving the problem: 103 | 104 | ``` 105 | 106 | 107 | dependencies: 108 | flutter: 109 | sdk: flutter 110 | 111 | # The following adds the Cupertino Icons font to your application. 112 | # Use with the CupertinoIcons class for iOS style icons. 113 | cupertino_icons: ^0.1.2 114 | 115 | # Route 116 | airoute: ^0.1.6 117 | provider: ^4.0.1 118 | oktoast: ^2.3.0 119 | 120 | 121 | 122 | ``` 123 | 124 | ``` 125 | void main() async { 126 | WidgetsFlutterBinding.ensureInitialized(); 127 | Provider.debugCheckInvalidValueType = null; 128 | 129 | SystemChrome.setPreferredOrientations( 130 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) { 131 | runApp(MultiProvider(providers: [ 132 | Provider.value( 133 | value: "this is test data", 134 | ), 135 | ], child: OKToast(child: StartupApplication()))); 136 | }); 137 | } 138 | 139 | ``` 140 | 141 | ``` 142 | 143 | 144 | class StartupApplication extends StatefulWidget { 145 | @override 146 | _StartupApplicationState createState() => _StartupApplicationState(); 147 | } 148 | 149 | class _StartupApplicationState extends State { 150 | @override 151 | Widget build(BuildContext context) { 152 | return Airoute.createMaterialApp( 153 | title: "Name", 154 | theme: ThemeData( 155 | fontFamily: 'IranSansLight', 156 | primaryColor: Color(0xFF823A84), 157 | accentColor: Color(0xFF823A84), 158 | textTheme: TextTheme( 159 | title: TextStyle(fontFamily: 'IranSansLight', color: Colors.black), 160 | ), 161 | ), 162 | home: LaunchPage(), 163 | routes: { 164 | "/LaunchPage": () => LaunchPage(), 165 | "/SecondPage": () => SecondPage(), 166 | }, 167 | ); 168 | } 169 | } 170 | 171 | 172 | ``` 173 | 174 | After solving the problem: 175 | 176 | ``` 177 | 178 | 179 | void main() async { 180 | WidgetsFlutterBinding.ensureInitialized(); 181 | Provider.debugCheckInvalidValueType = null; 182 | 183 | SystemChrome.setPreferredOrientations( 184 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]) 185 | .then((_) {}); 186 | runApp( 187 | MultiProvider( 188 | providers: [ 189 | Provider.value( 190 | value: "this is test data", 191 | ), 192 | ], 193 | child: OKToast( 194 | child: Airoute.createMaterialApp( 195 | title: "Name", 196 | theme: ThemeData( 197 | fontFamily: 'IranSansLight', 198 | primaryColor: Color(0xFF823A84), 199 | accentColor: Color(0xFF823A84), 200 | textTheme: TextTheme( 201 | title: 202 | TextStyle(fontFamily: 'IranSansLight', color: Colors.black), 203 | ), 204 | ), 205 | home: StartupApplication(), 206 | routes: { 207 | "/LaunchPage": () => LaunchPage(), 208 | "/SecondPage": () => SecondPage(), 209 | }, 210 | ), 211 | ), 212 | ), 213 | ); 214 | } 215 | 216 | class StartupApplication extends StatefulWidget { 217 | @override 218 | _StartupApplicationState createState() => _StartupApplicationState(); 219 | } 220 | 221 | class _StartupApplicationState extends State { 222 | @override 223 | Widget build(BuildContext context) { 224 | return Scaffold( 225 | appBar: AppBar( 226 | title: Text('Airoute'), 227 | ), 228 | body: Center( 229 | child: Text("Welcome......!"), 230 | ), 231 | ); 232 | } 233 | } 234 | 235 | 236 | ``` 237 | 238 | 239 | ----- -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | airoute: 5 | dependency: "direct main" 6 | description: 7 | path: ".." 8 | relative: true 9 | source: path 10 | version: "3.2.4" 11 | async: 12 | dependency: transitive 13 | description: 14 | name: async 15 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 16 | url: "https://pub.flutter-io.cn" 17 | source: hosted 18 | version: "2.11.0" 19 | boolean_selector: 20 | dependency: transitive 21 | description: 22 | name: boolean_selector 23 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 24 | url: "https://pub.flutter-io.cn" 25 | source: hosted 26 | version: "2.1.1" 27 | characters: 28 | dependency: transitive 29 | description: 30 | name: characters 31 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 32 | url: "https://pub.flutter-io.cn" 33 | source: hosted 34 | version: "1.3.0" 35 | clock: 36 | dependency: transitive 37 | description: 38 | name: clock 39 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 40 | url: "https://pub.flutter-io.cn" 41 | source: hosted 42 | version: "1.1.1" 43 | collection: 44 | dependency: transitive 45 | description: 46 | name: collection 47 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 48 | url: "https://pub.flutter-io.cn" 49 | source: hosted 50 | version: "1.18.0" 51 | cupertino_icons: 52 | dependency: "direct main" 53 | description: 54 | name: cupertino_icons 55 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 56 | url: "https://pub.flutter-io.cn" 57 | source: hosted 58 | version: "1.0.8" 59 | fake_async: 60 | dependency: transitive 61 | description: 62 | name: fake_async 63 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 64 | url: "https://pub.flutter-io.cn" 65 | source: hosted 66 | version: "1.3.1" 67 | flutter: 68 | dependency: "direct main" 69 | description: flutter 70 | source: sdk 71 | version: "0.0.0" 72 | flutter_test: 73 | dependency: "direct dev" 74 | description: flutter 75 | source: sdk 76 | version: "0.0.0" 77 | leak_tracker: 78 | dependency: transitive 79 | description: 80 | name: leak_tracker 81 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 82 | url: "https://pub.flutter-io.cn" 83 | source: hosted 84 | version: "10.0.5" 85 | leak_tracker_flutter_testing: 86 | dependency: transitive 87 | description: 88 | name: leak_tracker_flutter_testing 89 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 90 | url: "https://pub.flutter-io.cn" 91 | source: hosted 92 | version: "3.0.5" 93 | leak_tracker_testing: 94 | dependency: transitive 95 | description: 96 | name: leak_tracker_testing 97 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 98 | url: "https://pub.flutter-io.cn" 99 | source: hosted 100 | version: "3.0.1" 101 | matcher: 102 | dependency: transitive 103 | description: 104 | name: matcher 105 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 106 | url: "https://pub.flutter-io.cn" 107 | source: hosted 108 | version: "0.12.16+1" 109 | material_color_utilities: 110 | dependency: transitive 111 | description: 112 | name: material_color_utilities 113 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 114 | url: "https://pub.flutter-io.cn" 115 | source: hosted 116 | version: "0.11.1" 117 | meta: 118 | dependency: transitive 119 | description: 120 | name: meta 121 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 122 | url: "https://pub.flutter-io.cn" 123 | source: hosted 124 | version: "1.15.0" 125 | path: 126 | dependency: transitive 127 | description: 128 | name: path 129 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 130 | url: "https://pub.flutter-io.cn" 131 | source: hosted 132 | version: "1.9.0" 133 | plugin_platform_interface: 134 | dependency: transitive 135 | description: 136 | name: plugin_platform_interface 137 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 138 | url: "https://pub.flutter-io.cn" 139 | source: hosted 140 | version: "2.1.8" 141 | sky_engine: 142 | dependency: transitive 143 | description: flutter 144 | source: sdk 145 | version: "0.0.99" 146 | source_span: 147 | dependency: transitive 148 | description: 149 | name: source_span 150 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 151 | url: "https://pub.flutter-io.cn" 152 | source: hosted 153 | version: "1.10.0" 154 | stack_trace: 155 | dependency: transitive 156 | description: 157 | name: stack_trace 158 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 159 | url: "https://pub.flutter-io.cn" 160 | source: hosted 161 | version: "1.11.1" 162 | stream_channel: 163 | dependency: transitive 164 | description: 165 | name: stream_channel 166 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 167 | url: "https://pub.flutter-io.cn" 168 | source: hosted 169 | version: "2.1.2" 170 | string_scanner: 171 | dependency: transitive 172 | description: 173 | name: string_scanner 174 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 175 | url: "https://pub.flutter-io.cn" 176 | source: hosted 177 | version: "1.2.0" 178 | term_glyph: 179 | dependency: transitive 180 | description: 181 | name: term_glyph 182 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 183 | url: "https://pub.flutter-io.cn" 184 | source: hosted 185 | version: "1.2.1" 186 | test_api: 187 | dependency: transitive 188 | description: 189 | name: test_api 190 | sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" 191 | url: "https://pub.flutter-io.cn" 192 | source: hosted 193 | version: "0.7.2" 194 | vector_math: 195 | dependency: transitive 196 | description: 197 | name: vector_math 198 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 199 | url: "https://pub.flutter-io.cn" 200 | source: hosted 201 | version: "2.1.4" 202 | vm_service: 203 | dependency: transitive 204 | description: 205 | name: vm_service 206 | sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" 207 | url: "https://pub.flutter-io.cn" 208 | source: hosted 209 | version: "14.2.5" 210 | webview_flutter: 211 | dependency: "direct main" 212 | description: 213 | name: webview_flutter 214 | sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec" 215 | url: "https://pub.flutter-io.cn" 216 | source: hosted 217 | version: "4.10.0" 218 | webview_flutter_android: 219 | dependency: transitive 220 | description: 221 | name: webview_flutter_android 222 | sha256: "285cedfd9441267f6cca8843458620b5fda1af75b04f5818d0441acda5d7df19" 223 | url: "https://pub.flutter-io.cn" 224 | source: hosted 225 | version: "4.1.0" 226 | webview_flutter_platform_interface: 227 | dependency: transitive 228 | description: 229 | name: webview_flutter_platform_interface 230 | sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d 231 | url: "https://pub.flutter-io.cn" 232 | source: hosted 233 | version: "2.10.0" 234 | webview_flutter_wkwebview: 235 | dependency: transitive 236 | description: 237 | name: webview_flutter_wkwebview 238 | sha256: b7e92f129482460951d96ef9a46b49db34bd2e1621685de26e9eaafd9674e7eb 239 | url: "https://pub.flutter-io.cn" 240 | source: hosted 241 | version: "3.16.3" 242 | sdks: 243 | dart: ">=3.5.0 <4.0.0" 244 | flutter: ">=3.24.0" 245 | -------------------------------------------------------------------------------- /lib/route/route.dart: -------------------------------------------------------------------------------- 1 | part of airoute; 2 | 3 | /// 4 | /// Animation 5 | typedef RoutePageAnimation = Widget Function(BuildContext? context, Animation? animation, Animation? secondaryAnimation, Widget? page); 6 | 7 | /// 8 | /// Route manager 9 | class RouteManager extends NavigatorObserver { 10 | /// 11 | /// Route config map. 12 | static Map _route = {}; 13 | 14 | /// 15 | /// RouteManager. 16 | static RouteManager? _singleInstance; 17 | 18 | /// 19 | /// StreamController. 20 | // ignore: close_sinks 21 | static StreamController? _streamController; 22 | 23 | /// 24 | /// Navigator. 25 | NavigatorState? navigator; 26 | 27 | /// 28 | /// RouteManaqer. 29 | RouteManager._(); 30 | 31 | /// 32 | /// Instance. 33 | static RouteManager getInstance() { 34 | if (_singleInstance == null) { 35 | _singleInstance = RouteManager._(); 36 | 37 | _streamController = StreamController.broadcast(); 38 | } 39 | return _singleInstance!; 40 | } 41 | 42 | /// 43 | /// Initialize routes[_route]. 44 | static Map initializeRoutes({ 45 | required Map routes, 46 | }) { 47 | _route = routes; 48 | return _route; 49 | } 50 | 51 | /// 52 | /// Initialize generate route. 53 | static Route initializeGenerateRoute(RouteSettings routeSettings) { 54 | String? routeName = routeSettings.name; 55 | dynamic arguments = routeSettings.arguments; 56 | //Builder. 57 | AirouteBuilder airBuilder = _route[routeName]!; 58 | // if (airBuilder == null) { 59 | // return CupertinoPageRoute(builder: (context) { 60 | // return Text("Unknown"); 61 | // }); 62 | // } 63 | Widget widget = airBuilder(); 64 | 65 | if (widget is AirArgumentReceiver) { 66 | AirArgumentReceiver argumentReceiver = widget as AirArgumentReceiver; 67 | argumentReceiver.receive( 68 | AirArgument( 69 | routeName: routeName!, 70 | argument: arguments, 71 | isInitialRoute: false, 72 | ), 73 | ); 74 | } 75 | 76 | return CupertinoPageRoute( 77 | builder: (_) { 78 | return widget; 79 | }, 80 | settings: routeSettings, 81 | ); 82 | } 83 | 84 | /// 85 | /// Routes. 86 | static List? _mRoutes; 87 | 88 | /// 89 | /// Route. 90 | List? get routes => _mRoutes; 91 | 92 | /// 93 | /// Current route. 94 | Route? get currentRoute => _mRoutes![_mRoutes!.length - 1]; 95 | 96 | StreamController? get streamController => _streamController; 97 | 98 | /// 99 | /// Context. 100 | BuildContext? context({ 101 | String? routeName, 102 | }) { 103 | if (routeName != null) { 104 | return PageRouteBuilder( 105 | settings: RouteSettings(name: routeName), 106 | pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) { 107 | return _route[routeName]!(); 108 | }, 109 | ).navigator?.context; 110 | } 111 | return currentRoute?.navigator?.context; 112 | } 113 | 114 | /// 115 | /// Replace. 116 | pushReplacementNamed({ 117 | required String routeName, 118 | dynamic argument, 119 | }) { 120 | return navigator?.pushReplacementNamed( 121 | routeName, 122 | arguments: argument, 123 | ); 124 | } 125 | 126 | /// 127 | /// Push. 128 | pushNamed({ 129 | required String routeName, 130 | dynamic argument, 131 | }) { 132 | return navigator?.pushNamed( 133 | routeName, 134 | arguments: argument, 135 | ); 136 | } 137 | 138 | /// 139 | /// push 140 | Future? push({ 141 | required Route route, 142 | }) { 143 | return navigator?.push(route); 144 | } 145 | 146 | /// 147 | /// Push with animation. 148 | pushNamedWithAnimation({ 149 | required String routeName, 150 | dynamic argument, 151 | RoutePageAnimation routePageAnimation = AirouteTransition.Slide, 152 | Duration duration = const Duration(milliseconds: 500), 153 | }) { 154 | return navigator?.push( 155 | PageRouteBuilder( 156 | transitionDuration: duration, 157 | settings: RouteSettings( 158 | name: routeName, 159 | arguments: argument, 160 | ), 161 | pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) { 162 | //WidgetBuilder 163 | AirouteBuilder airouteBuilder = _route[routeName]!; 164 | Widget widget = airouteBuilder(); 165 | if (widget is AirArgumentReceiver) { 166 | AirArgumentReceiver argumentReceiver = widget as AirArgumentReceiver; 167 | argumentReceiver.receive( 168 | AirArgument( 169 | argument: argument, 170 | routeName: routeName, 171 | ), 172 | ); 173 | } 174 | //Route page animation 175 | return routePageAnimation( 176 | context, 177 | animation, 178 | secondaryAnimation, 179 | widget, 180 | ); 181 | }, 182 | ), 183 | ); 184 | } 185 | 186 | /// 187 | /// Pop. 188 | pop({ 189 | dynamic result, 190 | }) { 191 | if (navigator?.canPop() ?? false) { 192 | navigator?.pop(result); 193 | } 194 | } 195 | 196 | /// 197 | /// PopUntil[untilRouteName]. 198 | popUntil({ 199 | required String? untilRouteName, 200 | }) { 201 | bool isPopAll = untilRouteName == null ? true : false; 202 | if (isPopAll) { 203 | navigator?.popUntil( 204 | (Route route) { 205 | return false; 206 | }, 207 | ); 208 | } else { 209 | navigator?.popUntil(ModalRoute.withName('$untilRouteName')); 210 | } 211 | } 212 | 213 | /// 214 | /// Push[newRouteName]and remove until [untilRouteName]. 215 | pushNamedAndRemoveUntil({ 216 | required String newRouteName, 217 | required String? untilRouteName, 218 | dynamic argument, 219 | RoutePageAnimation routePageAnimation = AirouteTransition.Slide, 220 | }) { 221 | bool isRemoveAll = untilRouteName == null ? true : false; 222 | 223 | if (isRemoveAll) { 224 | //remove all. 225 | return navigator?.pushNamedAndRemoveUntil( 226 | newRouteName, 227 | (Route route) { 228 | return false; 229 | }, 230 | arguments: argument, 231 | ); 232 | } else { 233 | //not remove all. 234 | return navigator?.pushNamedAndRemoveUntil( 235 | newRouteName, 236 | ModalRoute.withName('$untilRouteName'), 237 | arguments: argument, 238 | ); 239 | } 240 | } 241 | 242 | /// 243 | /// DisPush. 244 | @override 245 | void didPush(Route route, Route? previousRoute) { 246 | super.didPush(route, previousRoute); 247 | if (_mRoutes == null) { 248 | _mRoutes = List.empty(); 249 | } 250 | // filter route type. 251 | if (route is CupertinoPageRoute || route is MaterialPageRoute) { 252 | _mRoutes!.add(route); 253 | routeObserver(); 254 | } 255 | } 256 | 257 | /// 258 | /// DisReplace. 259 | @override 260 | void didReplace({Route? newRoute, Route? oldRoute}) { 261 | super.didReplace(); 262 | if (newRoute is CupertinoPageRoute || newRoute is MaterialPageRoute) { 263 | _mRoutes!.remove(oldRoute); 264 | _mRoutes!.add(newRoute!); 265 | routeObserver(); 266 | } 267 | } 268 | 269 | /// 270 | /// DidPop. 271 | @override 272 | void didPop(Route route, Route? previousRoute) { 273 | super.didPop(route, previousRoute); 274 | if (route is CupertinoPageRoute || route is MaterialPageRoute) { 275 | _mRoutes!.remove(route); 276 | routeObserver(); 277 | } 278 | } 279 | 280 | /// 281 | /// DidRemove. 282 | @override 283 | void didRemove(Route removedRoute, Route? oldRoute) { 284 | super.didRemove(removedRoute, oldRoute); 285 | if (removedRoute is CupertinoPageRoute || removedRoute is MaterialPageRoute) { 286 | _mRoutes!.remove(removedRoute); 287 | routeObserver(); 288 | } 289 | } 290 | 291 | /// 292 | /// RouteObserver. 293 | void routeObserver() { 294 | navigator = _mRoutes![_mRoutes!.length - 1].navigator!; 295 | streamController!.sink.add(_mRoutes); 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /lib/route/airoute.dart: -------------------------------------------------------------------------------- 1 | part of airoute; 2 | 3 | /// 4 | /// Airoute 5 | class Airoute { 6 | /// 7 | /// Create MaterialApp. 8 | static MaterialApp createMaterialApp({ 9 | Key? key, 10 | GlobalKey? navigatorKey, 11 | Widget? home, 12 | Map routes = const {}, 13 | String? initialRoute, 14 | RouteFactory? onGenerateRoute, 15 | RouteFactory? onUnknownRoute, 16 | List navigatorObservers = const [], 17 | TransitionBuilder? builder, 18 | String title = '', 19 | GenerateAppTitle? onGenerateTitle, 20 | Color? color, 21 | ThemeData? theme, 22 | ThemeData? darkTheme, 23 | ThemeMode themeMode = ThemeMode.system, 24 | Locale? locale, 25 | Iterable>? localizationsDelegates, 26 | LocaleListResolutionCallback? localeListResolutionCallback, 27 | LocaleResolutionCallback? localeResolutionCallback, 28 | Iterable supportedLocales = const [Locale('en', 'US')], 29 | bool debugShowMaterialGrid = false, 30 | bool showPerformanceOverlay = false, 31 | bool checkerboardRasterCacheImages = false, 32 | bool checkerboardOffscreenLayers = false, 33 | bool showSemanticsDebugger = false, 34 | bool debugShowCheckedModeBanner = true, 35 | Map? shortcuts, 36 | Map>? actions, 37 | }) { 38 | return AirouteApp.createMaterialApp( 39 | key: key, 40 | navigatorKey: navigatorKey, 41 | home: home, 42 | routes: routes, 43 | initialRoute: initialRoute, 44 | onGenerateRoute: onGenerateRoute, 45 | onUnknownRoute: onUnknownRoute, 46 | navigatorObservers: navigatorObservers, 47 | builder: builder, 48 | title: title, 49 | onGenerateTitle: onGenerateTitle, 50 | color: color, 51 | theme: theme, 52 | darkTheme: darkTheme, 53 | themeMode: themeMode, 54 | locale: locale, 55 | localizationsDelegates: localizationsDelegates, 56 | localeListResolutionCallback: localeListResolutionCallback, 57 | localeResolutionCallback: localeResolutionCallback, 58 | supportedLocales: supportedLocales, 59 | debugShowMaterialGrid: debugShowMaterialGrid, 60 | showPerformanceOverlay: showPerformanceOverlay, 61 | checkerboardRasterCacheImages: checkerboardRasterCacheImages, 62 | checkerboardOffscreenLayers: checkerboardOffscreenLayers, 63 | showSemanticsDebugger: showSemanticsDebugger, 64 | debugShowCheckedModeBanner: debugShowCheckedModeBanner, 65 | shortcuts: shortcuts, 66 | actions: actions, 67 | ); 68 | } 69 | 70 | /// 71 | /// Create CupertinoApp. 72 | static CupertinoApp createCupertinoApp({ 73 | Key? key, 74 | GlobalKey? navigatorKey, 75 | Widget? home, 76 | Map routes = const {}, 77 | String? initialRoute, 78 | RouteFactory? onGenerateRoute, 79 | RouteFactory? onUnknownRoute, 80 | List navigatorObservers = const [], 81 | TransitionBuilder? builder, 82 | String title = '', 83 | GenerateAppTitle? onGenerateTitle, 84 | Color? color, 85 | ThemeData? theme, 86 | ThemeData? darkTheme, 87 | ThemeMode themeMode = ThemeMode.system, 88 | Locale? locale, 89 | Iterable>? localizationsDelegates, 90 | LocaleListResolutionCallback? localeListResolutionCallback, 91 | LocaleResolutionCallback? localeResolutionCallback, 92 | Iterable supportedLocales = const [Locale('en', 'US')], 93 | bool debugShowMaterialGrid = false, 94 | bool showPerformanceOverlay = false, 95 | bool checkerboardRasterCacheImages = false, 96 | bool checkerboardOffscreenLayers = false, 97 | bool showSemanticsDebugger = false, 98 | bool debugShowCheckedModeBanner = true, 99 | Map? shortcuts, 100 | Map>? actions, 101 | }) { 102 | return AirouteApp.createCupertinoApp( 103 | key: key, 104 | navigatorKey: navigatorKey, 105 | home: home, 106 | routes: routes, 107 | initialRoute: initialRoute, 108 | onGenerateRoute: onGenerateRoute, 109 | onUnknownRoute: onUnknownRoute, 110 | navigatorObservers: navigatorObservers, 111 | builder: builder, 112 | title: title, 113 | onGenerateTitle: onGenerateTitle, 114 | color: color, 115 | themeMode: themeMode, 116 | locale: locale, 117 | localizationsDelegates: localizationsDelegates, 118 | localeListResolutionCallback: localeListResolutionCallback, 119 | localeResolutionCallback: localeResolutionCallback, 120 | supportedLocales: supportedLocales, 121 | debugShowMaterialGrid: debugShowMaterialGrid, 122 | showPerformanceOverlay: showPerformanceOverlay, 123 | checkerboardRasterCacheImages: checkerboardRasterCacheImages, 124 | checkerboardOffscreenLayers: checkerboardOffscreenLayers, 125 | showSemanticsDebugger: showSemanticsDebugger, 126 | debugShowCheckedModeBanner: debugShowCheckedModeBanner, 127 | shortcuts: shortcuts, 128 | actions: actions, 129 | ); 130 | } 131 | 132 | /// 133 | /// Create WidgetsApp. 134 | static WidgetsApp createWidgetsApp({ 135 | Key? key, 136 | GlobalKey? navigatorKey, 137 | Widget? home, 138 | Map routes = const {}, 139 | String? initialRoute, 140 | RouteFactory? onGenerateRoute, 141 | RouteFactory? onUnknownRoute, 142 | List navigatorObservers = const [], 143 | TransitionBuilder? builder, 144 | String title = '', 145 | GenerateAppTitle? onGenerateTitle, 146 | required color, 147 | ThemeData? theme, 148 | ThemeData? darkTheme, 149 | ThemeMode themeMode = ThemeMode.system, 150 | Locale? locale, 151 | Iterable>? localizationsDelegates, 152 | LocaleListResolutionCallback? localeListResolutionCallback, 153 | LocaleResolutionCallback? localeResolutionCallback, 154 | Iterable supportedLocales = const [Locale('en', 'US')], 155 | bool debugShowMaterialGrid = false, 156 | bool showPerformanceOverlay = false, 157 | bool checkerboardRasterCacheImages = false, 158 | bool checkerboardOffscreenLayers = false, 159 | bool showSemanticsDebugger = false, 160 | bool debugShowCheckedModeBanner = true, 161 | Map? shortcuts, 162 | Map>? actions, 163 | }) { 164 | return AirouteApp.createWidgetsApp( 165 | key: key, 166 | navigatorKey: navigatorKey, 167 | home: home, 168 | routes: routes, 169 | initialRoute: initialRoute, 170 | onGenerateRoute: onGenerateRoute, 171 | onUnknownRoute: onUnknownRoute, 172 | navigatorObservers: navigatorObservers, 173 | builder: builder, 174 | title: title, 175 | onGenerateTitle: onGenerateTitle, 176 | color: color, 177 | themeMode: themeMode, 178 | locale: locale, 179 | localizationsDelegates: localizationsDelegates, 180 | localeListResolutionCallback: localeListResolutionCallback, 181 | localeResolutionCallback: localeResolutionCallback, 182 | supportedLocales: supportedLocales, 183 | debugShowMaterialGrid: debugShowMaterialGrid, 184 | showPerformanceOverlay: showPerformanceOverlay, 185 | checkerboardRasterCacheImages: checkerboardRasterCacheImages, 186 | checkerboardOffscreenLayers: checkerboardOffscreenLayers, 187 | showSemanticsDebugger: showSemanticsDebugger, 188 | debugShowCheckedModeBanner: debugShowCheckedModeBanner, 189 | shortcuts: shortcuts, 190 | actions: actions, 191 | ); 192 | } 193 | 194 | /// 195 | /// Replace. 196 | static pushReplacementNamed({ 197 | required String routeName, 198 | dynamic argument, 199 | }) { 200 | return NavigatorManager.getInstance()?.pushReplacementNamed( 201 | routeName: routeName, 202 | argument: argument, 203 | ); 204 | } 205 | 206 | /// 207 | /// Push. 208 | static pushNamed({ 209 | required String routeName, 210 | dynamic argument, 211 | }) { 212 | return NavigatorManager.getInstance()?.pushNamed( 213 | routeName: routeName, 214 | argument: argument, 215 | ); 216 | } 217 | 218 | /// 219 | /// push 220 | static Future? push({ 221 | required Route route, 222 | }) { 223 | return NavigatorManager.getInstance()?.push( 224 | route: route, 225 | ); 226 | } 227 | 228 | /// 229 | /// Push with animation. 230 | static pushNamedWithAnimation({ 231 | required String routeName, 232 | dynamic argument, 233 | RoutePageAnimation routePageAnimation = AirouteTransition.Fade, 234 | Duration duration = const Duration(milliseconds: 500), 235 | }) { 236 | return NavigatorManager.getInstance()?.pushNamedWithAnimation( 237 | routeName: routeName, 238 | argument: argument, 239 | routePageAnimation: routePageAnimation, 240 | duration: duration, 241 | ); 242 | } 243 | 244 | /// 245 | /// Pop. 246 | static pop({ 247 | dynamic result, 248 | }) { 249 | NavigatorManager.getInstance()?.pop( 250 | result: result, 251 | ); 252 | } 253 | 254 | /// 255 | /// PopUntil[untilRouteName]. 256 | static popUntil({ 257 | required String untilRouteName, 258 | }) { 259 | NavigatorManager.getInstance()?.popUntil( 260 | untilRouteName: untilRouteName, 261 | ); 262 | } 263 | 264 | /// 265 | /// Push[newRouteName]and remove until [untilRouteName]. 266 | static pushNamedAndRemoveUntil({ 267 | required String newRouteName, 268 | String? untilRouteName, 269 | dynamic argument, 270 | RoutePageAnimation routePageAnimation = AirouteTransition.Fade, 271 | }) { 272 | NavigatorManager.getInstance()?.pushNamedAndRemoveUntil( 273 | newRouteName: newRouteName, 274 | untilRouteName: untilRouteName, 275 | argument: argument, 276 | routePageAnimation: routePageAnimation, 277 | ); 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Airoute example | 爱路由 示例 2 | 3 | ![totem](https://raw.githubusercontent.com/pdliuw/pdliuw.github.io/master/images/totem_four_logo.jpg) 4 | 5 | ----- 6 | 7 | |[English Document](https://github.com/pdliuw/airoute/blob/master/example/README_EN.md)|[中文文档](https://github.com/pdliuw/airoute/tree/master/example)| 8 | |:-|:-| 9 | 10 | ## 我们的宗旨是:帮助开发者更加便利开发、切身体会编程之美! 11 | 12 | ### airoute: 13 | 14 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 15 | 16 | *1、支持无需context的路由管理, 17 | 18 | *2、支持‘非侵入式参数传递’的路由管理, 19 | 20 | *3、让你爱上路由管理的airoute 21 | 22 | [Airoute](https://github.com/pdliuw/airoute) 在[项目](https://github.com/flutter-app-sample/flutter_app_sample)中的实战应用[flutter sample](https://github.com/flutter-app-sample/flutter_app_sample) 23 | 24 | 25 | ## 使用介绍 26 | 27 | ### 1、全局配置 28 | 29 | ``` 30 | 31 | import 'package:airoute/airoute.dart'; 32 | import 'package:example/page/launch_page.dart'; 33 | import 'package:example/page/second_page.dart'; 34 | import 'package:example/page/third_page.dart'; 35 | import 'package:flutter/cupertino.dart'; 36 | import 'package:flutter/material.dart'; 37 | 38 | void main() { 39 | runApp(MyApp()); 40 | } 41 | 42 | class MyApp extends StatefulWidget { 43 | @override 44 | State createState() { 45 | return AppState(); 46 | } 47 | } 48 | 49 | class AppState extends State { 50 | @override 51 | Widget build(BuildContext context) { 52 | return Airoute.createMaterialApp( 53 | home: LaunchPage(), 54 | routes: { 55 | "/LaunchPage": (_) => LaunchPage(), 56 | "/SecondPage": (_) => SecondPage(), 57 | "/ThirdPage": (_) => ThirdPage(), 58 | }, 59 | ); 60 | } 61 | } 62 | 63 | 64 | 65 | ``` 66 | 67 | ### 2、LaunchPage 68 | 69 | ``` 70 | 71 | import 'dart:ui'; 72 | 73 | import 'package:airoute/airoute.dart'; 74 | import 'package:flutter/material.dart'; 75 | 76 | /// 77 | /// LaunchPage 78 | class LaunchPage extends StatefulWidget with AirArgumentReceiver { 79 | dynamic _content = ""; 80 | @override 81 | void receive(AirArgument argument) { 82 | _content = argument.argument['content']; 83 | } 84 | 85 | @override 86 | State createState() { 87 | return _LaunchState(); 88 | } 89 | } 90 | 91 | /// _LaunchState 92 | class _LaunchState extends State { 93 | String _content = ""; 94 | @override 95 | Widget build(BuildContext context) { 96 | Size size = window.physicalSize; 97 | double width = size.width / window.devicePixelRatio; 98 | double height = size.height / window.devicePixelRatio; 99 | 100 | return Scaffold( 101 | appBar: AppBar( 102 | title: Text("LaunchPage"), 103 | ), 104 | body: SingleChildScrollView( 105 | child: Column( 106 | children: [ 107 | Text("Hello world ${widget._content}"), 108 | Container( 109 | width: width, 110 | height: height / 2, 111 | padding: EdgeInsets.only( 112 | left: 20, 113 | top: 20, 114 | right: 20, 115 | bottom: 20, 116 | ), 117 | child: Center( 118 | child: TextField( 119 | enabled: true, 120 | decoration: InputDecoration( 121 | icon: Text("参数"), 122 | prefixIcon: Icon(Icons.phone_android), 123 | ), 124 | onChanged: (String content) { 125 | _content = content; 126 | }, 127 | ), 128 | ), 129 | ), 130 | MaterialButton( 131 | onPressed: () { 132 | // Airoute.pushNamedWithAnimation( 133 | // routeName: "/SecondPage", 134 | // routePageAnimation: ( 135 | // BuildContext context, 136 | // Animation animation, 137 | // Animation secondaryAnimation, 138 | // Widget page, 139 | // ) { 140 | // return SlideTransition( 141 | // position: Tween( 142 | // begin: const Offset(1.0, 0.0), 143 | // end: const Offset(0.0, 0.0), 144 | // ).animate(animation), 145 | // child: page, 146 | // ); 147 | // }, 148 | // ); 149 | // Airoute.pushNamed( 150 | // routeName: "/SecondPage", 151 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 152 | // ); 153 | // Airoute.pushNamedWithAnimation( 154 | // routeName: "/SecondPage", 155 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 156 | // duration: Duration(milliseconds: 800), 157 | // routePageAnimation: ( 158 | // BuildContext context, 159 | // Animation animation, 160 | // Animation secondaryAnimation, 161 | // Widget page, 162 | // ) { 163 | // return FadeTransition( 164 | // opacity: CurvedAnimation( 165 | // parent: animation, curve: Curves.easeOut), 166 | // child: SlideTransition( 167 | // position: Tween( 168 | // begin: const Offset(1.0, 0.0), 169 | // end: const Offset(0.0, 0.0), 170 | // ).animate(animation), 171 | // child: page, 172 | // ), 173 | // ); 174 | // }, 175 | // ); 176 | // Airoute.pushNamedWithAnimation( 177 | // routeName: "/SecondPage", 178 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 179 | // routePageAnimation: AirouteTransition.Slide, 180 | // duration: Duration(milliseconds: 500), 181 | // ); 182 | // Airoute.pushNamedWithAnimation( 183 | // routeName: "/routeName", 184 | // argument: "$_content \n 遇见你,我很开心😄😄😄", 185 | //// duration: Duration(milliseconds: 500), 186 | // routePageAnimation: _slide, 187 | // ); 188 | Airoute.pushNamedWithAnimation( 189 | routeName: "/SecondPage", 190 | argument: "$_content \n happy to see you", 191 | routePageAnimation: AirouteTransition.Slide, 192 | ); 193 | }, 194 | color: Theme.of(context).primaryColor, 195 | textColor: Colors.white, 196 | child: Text("跳转下一页"), 197 | ), 198 | ], 199 | ), 200 | ), 201 | ); 202 | } 203 | } 204 | 205 | 206 | ``` 207 | 208 | ### 3、SecondPage 209 | 210 | ``` 211 | 212 | import 'package:flutter/material.dart'; 213 | import 'package:airoute/airoute.dart'; 214 | 215 | /// 216 | /// SecondPage 217 | class SecondPage extends StatefulWidget with AirArgumentReceiver { 218 | dynamic _content; 219 | @override 220 | State createState() { 221 | return _SecondPageState(); 222 | } 223 | 224 | @override 225 | void receive(AirArgument argument) { 226 | _content = argument.argument; 227 | print("收到${argument.argument}参数了,我很开心😄😄😄"); 228 | } 229 | } 230 | 231 | /// 232 | /// _SecondPageState 233 | class _SecondPageState extends State { 234 | @override 235 | Widget build(BuildContext context) { 236 | return Scaffold( 237 | backgroundColor: Colors.blue, 238 | appBar: AppBar( 239 | elevation: 0, 240 | title: Text("SecondPage"), 241 | ), 242 | body: Center( 243 | child: Column( 244 | children: [ 245 | Text( 246 | "以下为上页传递的数据\n\n\n${widget._content}", 247 | style: TextStyle( 248 | color: Colors.white, 249 | ), 250 | textAlign: TextAlign.center, 251 | ), 252 | RaisedButton.icon( 253 | onPressed: () { 254 | Airoute.pushNamed(routeName: "/ThirdPage", argument: "Air"); 255 | }, 256 | icon: Icon(Icons.arrow_right), 257 | label: Text("Next"), 258 | ), 259 | ], 260 | ), 261 | ), 262 | ); 263 | } 264 | } 265 | 266 | 267 | ``` 268 | 269 | ### 4、ThirdPage 270 | 271 | ``` 272 | 273 | import 'package:flutter/material.dart'; 274 | import 'package:airoute/airoute.dart'; 275 | 276 | /// 277 | /// ThirdPage 278 | class ThirdPage extends StatefulWidget with AirArgumentReceiver { 279 | dynamic _content; 280 | @override 281 | State createState() { 282 | return _ThirdPageState(); 283 | } 284 | 285 | @override 286 | void receive(AirArgument argument) { 287 | _content = argument.argument; 288 | print("收到${argument.argument}参数了,我很开心😄😄😄"); 289 | } 290 | } 291 | 292 | /// 293 | /// _SecondPageState 294 | class _ThirdPageState extends State { 295 | @override 296 | Widget build(BuildContext context) { 297 | return Scaffold( 298 | backgroundColor: Colors.blue, 299 | appBar: AppBar( 300 | elevation: 0, 301 | title: Text("ThirdPage"), 302 | ), 303 | body: Center( 304 | child: Column( 305 | children: [ 306 | Text( 307 | "以下为上页传递的数据\n\n\n${widget._content}", 308 | style: TextStyle( 309 | color: Colors.white, 310 | ), 311 | textAlign: TextAlign.center, 312 | ), 313 | RaisedButton.icon( 314 | onPressed: () { 315 | Airoute.popUntil(untilRouteName: "/SecondPage"); 316 | }, 317 | icon: Icon(Icons.arrow_back), 318 | label: Text("Back"), 319 | ), 320 | RaisedButton.icon( 321 | onPressed: () { 322 | Airoute.pushNamed(routeName: "/ThirdPage", argument: "Repeat"); 323 | }, 324 | icon: Icon(Icons.arrow_right), 325 | label: Text("Next"), 326 | ), 327 | ], 328 | ), 329 | ), 330 | ); 331 | } 332 | } 333 | 334 | 335 | ``` -------------------------------------------------------------------------------- /example/README_EN.md: -------------------------------------------------------------------------------- 1 | # Airoute example 2 | 3 | ![totem](https://raw.githubusercontent.com/pdliuw/pdliuw.github.io/master/images/totem_four_logo.jpg) 4 | 5 | ----- 6 | 7 | |[English Document](https://github.com/pdliuw/airoute/blob/master/example/README_EN.md)|[中文文档](https://github.com/pdliuw/airoute/tree/master/example)| 8 | |:-|:-| 9 | 10 | ## Our aim is to help developers make development more convenient and experience the beauty of programming! 11 | 12 | ### airoute: 13 | 14 | [![pub package](https://img.shields.io/pub/v/airoute.svg)](https://pub.dev/packages/airoute) 15 | 16 | *1、Support routing management without context 17 | 18 | *2、Support 'non-intrusive parameter passing' routing management 19 | 20 | *3、Airoute that makes you fall in love with routing management 21 | 22 | [Airoute](https://github.com/pdliuw/airoute) in the[Project](https://github.com/flutter-app-sample/flutter_app_sample)Practical application[flutter sample](https://github.com/flutter-app-sample/flutter_app_sample) 23 | 24 | 25 | ## Usage 26 | 27 | ### 1、Global config 28 | 29 | ``` 30 | 31 | import 'package:airoute/airoute.dart'; 32 | import 'package:example/page/launch_page.dart'; 33 | import 'package:example/page/second_page.dart'; 34 | import 'package:example/page/third_page.dart'; 35 | import 'package:flutter/cupertino.dart'; 36 | import 'package:flutter/material.dart'; 37 | 38 | void main() { 39 | runApp(MyApp()); 40 | } 41 | 42 | class MyApp extends StatefulWidget { 43 | @override 44 | State createState() { 45 | return AppState(); 46 | } 47 | } 48 | 49 | class AppState extends State { 50 | @override 51 | Widget build(BuildContext context) { 52 | return Airoute.createMaterialApp( 53 | home: LaunchPage(), 54 | routes: { 55 | "/LaunchPage": (_) => LaunchPage(), 56 | "/SecondPage": (_) => SecondPage(), 57 | "/ThirdPage": (_) => ThirdPage(), 58 | }, 59 | ); 60 | } 61 | } 62 | 63 | 64 | 65 | ``` 66 | 67 | ### 2、LaunchPage 68 | 69 | ``` 70 | 71 | 72 | import 'dart:ui'; 73 | 74 | import 'package:airoute/airoute.dart'; 75 | import 'package:flutter/material.dart'; 76 | 77 | /// 78 | /// LaunchPage 79 | class LaunchPage extends StatefulWidget with AirArgumentReceiver { 80 | dynamic _content = ""; 81 | @override 82 | void receive(AirArgument argument) { 83 | _content = argument.argument['content']; 84 | } 85 | 86 | @override 87 | State createState() { 88 | return _LaunchState(); 89 | } 90 | } 91 | 92 | /// _LaunchState 93 | class _LaunchState extends State { 94 | String _content = ""; 95 | @override 96 | Widget build(BuildContext context) { 97 | Size size = window.physicalSize; 98 | double width = size.width / window.devicePixelRatio; 99 | double height = size.height / window.devicePixelRatio; 100 | 101 | return Scaffold( 102 | appBar: AppBar( 103 | title: Text("LaunchPage"), 104 | ), 105 | body: SingleChildScrollView( 106 | child: Column( 107 | children: [ 108 | Text("Hello world ${widget._content}"), 109 | Container( 110 | width: width, 111 | height: height / 2, 112 | padding: EdgeInsets.only( 113 | left: 20, 114 | top: 20, 115 | right: 20, 116 | bottom: 20, 117 | ), 118 | child: Center( 119 | child: TextField( 120 | enabled: true, 121 | decoration: InputDecoration( 122 | icon: Text("argument"), 123 | prefixIcon: Icon(Icons.phone_android), 124 | ), 125 | onChanged: (String content) { 126 | _content = content; 127 | }, 128 | ), 129 | ), 130 | ), 131 | MaterialButton( 132 | onPressed: () { 133 | // Airoute.pushNamedWithAnimation( 134 | // routeName: "/SecondPage", 135 | // routePageAnimation: ( 136 | // BuildContext context, 137 | // Animation animation, 138 | // Animation secondaryAnimation, 139 | // Widget page, 140 | // ) { 141 | // return SlideTransition( 142 | // position: Tween( 143 | // begin: const Offset(1.0, 0.0), 144 | // end: const Offset(0.0, 0.0), 145 | // ).animate(animation), 146 | // child: page, 147 | // ); 148 | // }, 149 | // ); 150 | // Airoute.pushNamed( 151 | // routeName: "/SecondPage", 152 | // argument: "$_content \n nice to meet you 😄😄😄", 153 | // ); 154 | // Airoute.pushNamedWithAnimation( 155 | // routeName: "/SecondPage", 156 | // argument: "$_content \n nice to meet you 😄😄😄", 157 | // duration: Duration(milliseconds: 800), 158 | // routePageAnimation: ( 159 | // BuildContext context, 160 | // Animation animation, 161 | // Animation secondaryAnimation, 162 | // Widget page, 163 | // ) { 164 | // return FadeTransition( 165 | // opacity: CurvedAnimation( 166 | // parent: animation, curve: Curves.easeOut), 167 | // child: SlideTransition( 168 | // position: Tween( 169 | // begin: const Offset(1.0, 0.0), 170 | // end: const Offset(0.0, 0.0), 171 | // ).animate(animation), 172 | // child: page, 173 | // ), 174 | // ); 175 | // }, 176 | // ); 177 | // Airoute.pushNamedWithAnimation( 178 | // routeName: "/SecondPage", 179 | // argument: "$_content \n nice to meet you 😄😄😄", 180 | // routePageAnimation: AirouteTransition.Slide, 181 | // duration: Duration(milliseconds: 500), 182 | // ); 183 | // Airoute.pushNamedWithAnimation( 184 | // routeName: "/routeName", 185 | // argument: "$_content \n nice to meet you 😄😄😄", 186 | //// duration: Duration(milliseconds: 500), 187 | // routePageAnimation: _slide, 188 | // ); 189 | Airoute.pushNamedWithAnimation( 190 | routeName: "/SecondPage", 191 | argument: "$_content \n happy to see you", 192 | routePageAnimation: AirouteTransition.Slide, 193 | ); 194 | }, 195 | color: Theme.of(context).primaryColor, 196 | textColor: Colors.white, 197 | child: Text("goto next page"), 198 | ), 199 | ], 200 | ), 201 | ), 202 | ); 203 | } 204 | } 205 | 206 | 207 | ``` 208 | 209 | ### 3、SecondPage 210 | 211 | ``` 212 | 213 | import 'package:flutter/material.dart'; 214 | import 'package:airoute/airoute.dart'; 215 | 216 | /// 217 | /// SecondPage 218 | class SecondPage extends StatefulWidget with AirArgumentReceiver { 219 | dynamic _content; 220 | @override 221 | State createState() { 222 | return _SecondPageState(); 223 | } 224 | 225 | @override 226 | void receive(AirArgument argument) { 227 | _content = argument.argument; 228 | print("receive{argument.argument}argument,i am so happy 😄😄😄"); 229 | } 230 | } 231 | 232 | /// 233 | /// _SecondPageState 234 | class _SecondPageState extends State { 235 | @override 236 | Widget build(BuildContext context) { 237 | return Scaffold( 238 | backgroundColor: Colors.blue, 239 | appBar: AppBar( 240 | elevation: 0, 241 | title: Text("SecondPage"), 242 | ), 243 | body: Center( 244 | child: Column( 245 | children: [ 246 | Text( 247 | "data:\n\n\n${widget._content}", 248 | style: TextStyle( 249 | color: Colors.white, 250 | ), 251 | textAlign: TextAlign.center, 252 | ), 253 | RaisedButton.icon( 254 | onPressed: () { 255 | Airoute.pushNamed(routeName: "/ThirdPage", argument: "Air"); 256 | }, 257 | icon: Icon(Icons.arrow_right), 258 | label: Text("Next"), 259 | ), 260 | ], 261 | ), 262 | ), 263 | ); 264 | } 265 | } 266 | 267 | 268 | ``` 269 | 270 | ### 4、ThirdPage 271 | 272 | ``` 273 | 274 | import 'package:flutter/material.dart'; 275 | import 'package:airoute/airoute.dart'; 276 | 277 | /// 278 | /// ThirdPage 279 | class ThirdPage extends StatefulWidget with AirArgumentReceiver { 280 | dynamic _content; 281 | @override 282 | State createState() { 283 | return _ThirdPageState(); 284 | } 285 | 286 | @override 287 | void receive(AirArgument argument) { 288 | _content = argument.argument; 289 | print("receive{argument.argument}argument,i am so happy😄😄😄"); 290 | } 291 | } 292 | 293 | /// 294 | /// _SecondPageState 295 | class _ThirdPageState extends State { 296 | @override 297 | Widget build(BuildContext context) { 298 | return Scaffold( 299 | backgroundColor: Colors.blue, 300 | appBar: AppBar( 301 | elevation: 0, 302 | title: Text("ThirdPage"), 303 | ), 304 | body: Center( 305 | child: Column( 306 | children: [ 307 | Text( 308 | "data:\n\n\n${widget._content}", 309 | style: TextStyle( 310 | color: Colors.white, 311 | ), 312 | textAlign: TextAlign.center, 313 | ), 314 | RaisedButton.icon( 315 | onPressed: () { 316 | Airoute.popUntil(untilRouteName: "/SecondPage"); 317 | }, 318 | icon: Icon(Icons.arrow_back), 319 | label: Text("Back"), 320 | ), 321 | RaisedButton.icon( 322 | onPressed: () { 323 | Airoute.pushNamed(routeName: "/ThirdPage", argument: "Repeat"); 324 | }, 325 | icon: Icon(Icons.arrow_right), 326 | label: Text("Next"), 327 | ), 328 | ], 329 | ), 330 | ), 331 | ); 332 | } 333 | } 334 | 335 | 336 | ``` -------------------------------------------------------------------------------- /example/macos/Runner/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | --------------------------------------------------------------------------------