توزيع مفصل للتنقل في Flutter

صورة



تكتسب Flutter شعبية بين المطورين. لقد تم بالفعل وضع معظم مناهج بناء التطبيقات ويتم استخدامها يوميًا في تطوير تطبيقات التجارة الإلكترونية. يتم تخفيض موضوع التنقل إلى الخلفية أو الخطة الثالثة. ما هي واجهة برمجة تطبيقات التنقل التي يوفرها Framework؟ ما هي الأساليب التي تم تطويرها؟ كيف يتم استخدام هذه الأساليب وما هي فائدتها؟



المقدمة



لنبدأ بما هو التنقل؟ التنقل هو طريقة تسمح لك بالتنقل بين واجهة المستخدم بمعلمات محددة.

على سبيل المثال ، في عالم IOS ، ينظم التنقل UIViewController ، وفي Android - مكون التنقل. ماذا يقدم Flutter؟





الشاشات في Flutter تسمى المسار. للتنقل بين المسارات ، توجد فئة Navigator تحتوي على واجهة برمجة تطبيقات شاملة لتنفيذ أنواع مختلفة من التنقل.





لنبدأ ببساطة. يتم استدعاء التنقل إلى شاشة جديدة (مسار) بواسطة طريقة push () ، والتي تأخذ وسيطة واحدة - هذا هو المسار.



Navigator.push(MaterialPageRoute(builder: (BuildContext context) => MyPage()));


دعنا نلقي نظرة فاحصة على استدعاء طريقة الدفع:



Navigator — , .

Navigator.push() — route   .

MaterialPageRoute() — route,   .

builder — MaterialPageRoute, .

MyPage — Stateful/Stateless Widget



route



pop().



Navigator.pop();




builder . Navigator, build.



Navigator.push(context, MaterialPageRoute(builder: (context) => MyPage(someData: data)));


MyPage ( ).



pop() .



Navigator.pop(data);




Navigator, MaterialApp/CupertinoApp/WidgetsApp. State API .

Stack. "call flow" NavigatorState.



https://habrastorage.org/webt/5w/dg/nb/5wdgnb-tjlngub4c8y4rlpqkeqi.png



vs



. route, .



:



,?

: , . .



, — ?

: , .



Imperative vs Declarative Programming





. . Route. Flutter route, MaterialPageRoute CupertinoPageRoute. CupertinoPageRoute title, settings.



:



Navigator.push(
    context,
    CupertinoPageRoute<T>(
        title: "Setting",
        builder: (BuildContext context) => MyPage(),
        settings: RouteSettings(name:"my_page"),
    ),
);


route   ViewModel/Controller/BLoC/… .



MyPage CupertinoPageRoute. push .



:



, route .




. .



:



Navigator.pushNamed(context, '/my_page');


. " " .

MaterialApp/CupertinoApp/WidgetsApp. 2 onGenerateRoute onUnknownRoute .



:



MaterialApp(
    onUnknownRoute: (settings) => CupertinoPageRoute(
      builder: (context) {
                return UndefinedView(name: settings.name);
            }
    ),
  onGenerateRoute: (settings) {
    if (settings.name == '\my_page') {
      return CupertinoPageRoute(
                title: "MyPage",
                settings: settings,
        builder: (context) => MyPage(),
      );
    }
        //     
  },
);


:

onGenerateRoute — Navigator.pushNamed(). route.

onUnknownRouteonGenerateRoute null. route, web — 404 page.



. , .




. .



:



  • showAboutDialog
  • showBottomSheet
  • showDatePicker
  • showGeneralDialog
  • showMenu
  • showModalBottomSheet
  • showSearch
  • showTimePicker
  • showCupertinoDialog
  • showDialog
  • showLicensePage
  • showCupertinoModalPopup


. API, .



?



, showGeneralDialog.



:



Future<T> showGeneralDialog<T>({
  @required BuildContext context,
  @required RoutePageBuilder pageBuilder,
  bool barrierDismissible,
  String barrierLabel,
  Color barrierColor,
  Duration transitionDuration,
  RouteTransitionsBuilder transitionBuilder,
  bool useRootNavigator = true,
  RouteSettings routeSettings,
}) {
  assert(pageBuilder != null);
  assert(useRootNavigator != null);
  assert(!barrierDismissible || barrierLabel != null);
  return Navigator.of(context, rootNavigator: useRootNavigator).push<T>(_DialogRoute<T>(
    pageBuilder: pageBuilder,
    barrierDismissible: barrierDismissible,
    barrierLabel: barrierLabel,
    barrierColor: barrierColor,
    transitionDuration: transitionDuration,
    transitionBuilder: transitionBuilder,
    settings: routeSettings,
  ));
}


. showGeneralDialog push NavigatorState _DialogRoute(). , .



— route .


route



 "every thins is a route", . , route .



route Flutter — PageRoute PopupRoute.



PageRoute — route, .

PopupRoute — route, route.



PageRoute:



  • MaterialPageRoute
  • CupertinoPageRoute
  • _SearchPageRoute
  • PageRouteBuilder


PopupRoute:



  • _ContexMenuRoute
  • _DialogRoute
  • _ModalBottomSheetRoute
  • _CupertinoModalPopupRoute
  • _PopupMenuRoute


PopupRoute , .



:



, .


Best practices



, " ?". , API , . .



:



  • .
  • BuildContext ( , BuildContext).
  • . route, CupertinoPageRoute, BottomSheetRoute, DialogRoute ..


:



abstract class IRouter {
  Future<T> routeTo<T extends Object>(RouteBundle bundle);
  Future<bool> back<T extends Object>({T data, bool rootNavigator});
  GlobalKey<NavigatorState> rootNavigatorKey;
}


:

routeTo - .

back — .

rootNavigatorKey — GlobalKey NavigatorState.

, .



class Router implements IRouter {
    @override
  GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();

    @override
  Future<T> routeTo<T>(RouteBundle bundle) async {
   // Push logic here
  }

    @override
  Future<bool> back<T>({T data, bool rootNavigator = false}) async {
        // Back logic here
    }
}


 , routeTo().



@override
  Future<T> routeTo<T>(RouteBundle bundle) async {
        assert(bundle != null, "The bundle [RouteBundle.bundle] is null");
    NavigatorState rootState = rootNavigatorKey.currentState;
    assert(rootState != null, 'rootState [NavigatorState] is null');

    switch (bundle.route) {
      case "/routeExample":
        return await rootState.push(
          _buildRoute<T>(
            bundle: bundle,
            child: RouteExample(),
          ),
        );

      case "/my_page":
        return await rootState.push(
          _buildRoute<T>(
            bundle: bundle,
            child: MyPage(),
          ),
        );
      default:
        throw Exception('Route is not found');
    }
  }


root NavigatorState ( WidgetsApp) push RouteBundle .



RouteBundle. , .



enum ContainerType {
  /// The parent type is [Scaffold].
  ///
  /// In IOS route with an iOS transition [CupertinoPageRoute].
  /// In Android route with an Android transition [MaterialPageRoute].
  ///
  scaffold,

  /// Used for show child in dialog.
  ///
  /// Route with [DialogRoute].
  dialog,

  /// Used for show child in [BottomSheet].
  ///
  /// Route with [ModalBottomSheetRoute].
  bottomSheet,

  /// Used for show child only.
  /// [AppBar] and other features is not implemented.
  window,
}
class RouteBundle {
  /// Creates a bundle that can be used for [Router].
  RouteBundle({
    this.route,
    this.containerType,
  });

  /// The route for current navigation.
  ///
  /// See [Routes] for details.
  final String route;

  /// The current status of this animation.
  final ContainerType containerType;
}


enum ContainerType — , .

RouteBundle — - route.



_buildRoute. , route .



Route<T> _buildRoute<T>({@required RouteBundle bundle, @required Widget child}) {
    assert(bundle.containerType != null, "The bundle.containerType [RouteBundle.containerType] is null");

    switch (bundle.containerType) {
      case ContainerType.scaffold:
        return CupertinoPageRoute<T>(
          title: bundle.title,
          builder: (BuildContext context) => child,
          settings: RouteSettings(name: bundle.route),
        );
      case ContainerType.dialog:
        return DialogRoute<T>(
          title: '123',
          settings: RouteSettings(name: bundle.route),
          pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
                        return child;
                    },
        );
      case ContainerType.bottomSheet:
        return ModalBottomSheetRoute<T>(
          settings: RouteSettings(name: bundle.route),
          isScrollControlled: true,
          builder: (BuildContext context) => child,
        );
      case ContainerType.window:
        return CupertinoPageRoute<T>(
          settings: RouteSettings(name: bundle.route),
          builder: (BuildContext context) => child,
        );
      default:
        throw Exception('ContainerType is not found');
    }
  }


ModalBottomSheetRoute DialogRoute, . route Material Flutter.



back.



@override
Future<bool> back<T>({T data, bool rootNavigator = false}) async {
    NavigatorState rootState = rootNavigatorKey.currentState;
  return await (rootState).maybePop<T>(data);
}


rootNavigatorKey App :



MaterialApp(
    navigatorKey: widget.router.rootNavigatorKey,
    home: Home()
);


, route. - "" , , Dependency Injection.



صورة



router.routeTo(RouteBundle(route: '/my_page', containerType: ContainerType.window));


, :



  • BuildContext GlobalKey
  • route View




Flutter , .



:



Flutter Dev Podcast

Flutter




All Articles