Всем привет, добро пожаловать на мой очередной урок. Сегодня у меня есть другая тема, которой я могу поделиться с вами. Как вы знаете, в моем предыдущем уроке я всегда делился с вами информацией о Riverpod. Итак, что я хотел бы сказать вам сегодня? Во Flutter иногда нам нужно мощное управление навигацией, которое мы можем использовать в нашем проекте Flutter. Один из замечательных пакетов, который Flutter должен оптимизировать наше управление навигацией, — это go_router.
Что такое go_router?
Пакет декларативной маршрутизации для Flutter, который использует Router API для предоставления удобного API на основе URL для навигации между различными экранами. Вы можете определять шаблоны URL-адресов, осуществлять навигацию с использованием URL-адресов, обрабатывать глубокие ссылки и ряд других сценариев, связанных с навигацией.
У go_router есть много преимуществ, позволяющих упростить навигацию:
Анализ пути и параметров запроса с использованием синтаксиса шаблона (например, «user/:id»)
Отображение нескольких экранов для пункта назначения (подмаршрутов)
Поддержка перенаправления — вы можете перенаправить пользователя на другой URL-адрес в зависимости от состояния приложения, например, на вход, когда пользователь не прошел проверку подлинности.
Поддержка нескольких навигаторов через ShellRoute — вы можете отобразить внутренний навигатор, который отображает свои страницы на основе согласованного маршрута. Например, чтобы отобразить BottomNavigationBar, который остается видимым в нижней части экрана.
Поддержка приложений Material и Cupertino.
Обратная совместимость с Navigator API
go_router похож на другое управление навигацией, но более мощное. В go_router мы можем передавать данные, используя свойство extra, которое нам предоставил go_router. К сожалению, go_router не поддерживает передачу нескольких данных.
Как вы можете видеть выше, go_router просто предоставляет нам возможность передать один объект. Существует проблема. Однако иногда в нашей разработке мы не просто передаем одни данные, вместо этого нам нужно передать 2 данных, 3 данных, 4 данных и т. д. Итак, как мы можем передать несколько данных с помощью go_router?
Хорошо, во-первых, давайте создадим проект.
import 'package:flutter/material.dart'; import 'package:go_router_example/routes/routing.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp.router( routerConfig: appRouter, ); } }
Над моим main.dart. Достаточно просто, не так ли?
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; class MyFirstScreen extends StatelessWidget { const MyFirstScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('My First Screen'), ), body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Center( child: ElevatedButton( onPressed: () { context.push('/second-screen'); }, style: ButtonStyle( fixedSize: MaterialStateProperty.all( Size(MediaQuery.of(context).size.width - 50, 50))), child: const Text('Navigate To Secon Screen')), ), ], ), ); } }
Я создал my_first_screen.dart. В MyFirstScreen я просто создаю кнопку, которую мы будем использовать для перехода на другие страницы, скажем, MySecondScreen.
Затем давайте создадим файл дротика с именем my_second_screen.dart. В MySecondScreen мы будем передавать данные с помощью конструктора.
import 'package:flutter/material.dart'; class MySecondScreen extends StatelessWidget { final String name; final int age; final String job; const MySecondScreen( {super.key, required this.name, required this.age, required this.job}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('My Second Screen'), ), body: Center( child: Column( children: [ Text( 'My name is $name', style: const TextStyle( fontSize: 18, ), ), Text( 'My age is $age', style: const TextStyle( fontSize: 18, ), ), Text( 'My job is $job', style: const TextStyle( fontSize: 18, ), ), ], ), ), ); } }
В нашем routing.dart мы получили ошибки. Потому что мы просто передали данные конструктором.
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:go_router_example/screen_1.dart'; import 'package:go_router_example/screen_2.dart'; final GoRouter appRouter = GoRouter( routes: <RouteBase>[ GoRoute( path: '/', builder: (BuildContext context, GoRouterState state) { return const MyFirstScreen(); }, routes: <RouteBase>[ GoRoute( path: 'second-screen', builder: (BuildContext context, GoRouterState state) { return MySecondScreen( age: , job: , name: , ); }, ), ], ), ], );
Да, как вы можете видеть выше, нам нужно передать данные требований (возраст, должность и имя). Для этого мы можем использовать функции, которые предоставил go_router. Мы можем указать (GoRouterState) для обработки данных требований. Я изменю свой файл routing.dart.
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:go_router_example/screen_1.dart'; import 'package:go_router_example/screen_2.dart'; final GoRouter appRouter = GoRouter( routes: <RouteBase>[ GoRoute( path: '/', builder: (BuildContext context, GoRouterState state) { return const MyFirstScreen(); }, routes: <RouteBase>[ GoRoute( path: 'second-screen', builder: (BuildContext context, GoRouterState state) { Map<String, dynamic> data = state.extra as Map<String, dynamic>; return MySecondScreen( age: data['age'], job: data['job'], name: data['name'], ); }, ), ], ), ], );
Выше я изменил свой файл routing.dart. Как видите, я только что преобразовал state.extra в Map. Без приведения state.extra мы получим ошибку. Потому что state.extra, который нам предоставил go_router, относится к типу Object. Итак, нам нужно разобрать тип объекта на Map.
Хорошо, давайте перейдем к нашему MyFirstScreen.
Map<String, dynamic> data = { 'age': 10, 'job': 'Flutter Developer', 'name': 'John', }; context.push('/second-screen', extra: data);
Я добавил данные в метод onPressed. Мы просто передаем данные как Map. Зачем нам нужно передавать данные как карту? Как вы знаете, в go_router мы не можем передавать несколько данных, потому что go_router поддерживает только одиночные данные (объект).
Итак, наш MyFirstScreen хотел бы,
Потрясающий! Наконец, мы решили одну из проблем с go_router. Надеюсь, вы, ребята, могли понять то, чем я делюсь с вами. Если у вас есть какие-либо вопросы, пожалуйста, сообщите мне ниже. Хорошо, спасибо за чтение, увидимся на следующем уроке!