Route
Так называемое управление маршрутизацией - управлять тем, как прыгать между страницами, также известными как управление навигацией. Это похоже на нативное развитие. Будь то Android или IOS, управление навигациями достигается путем поддержания стека маршрутизации. Работа на нагрузке соответствует открытию новой страницы, а операция POP маршрутизации соответствует операции закрытия страницы. В разработке трепетания маршрут и навигатор должны использоваться одновременно для реализации прыжка страницы.
- Маршрут — абстрактный экран или страница приложения;
- Навигатор — виджет, управляющий маршрутизацией;
Маршрут обычно используется для представления страницы (Page) мобильных приложений в мобильной разработке, В частности, маршрут обычно относится к Activity в Android и ViewController в iOS.
Navigator — это виджет управления маршрутизацией, который управляет набором виджетов маршрутизации через стек. Обычно страница, отображаемая на текущем экране, является маршрутом наверху стека.Навигатор предоставляет ряд методов для управления стеком маршрутизации.
Пример
Чтобы проиллюстрировать, как Flutter реализует переходы маршрутизации, мы создаем две страницы: NewRoute.dart и main.dart. Среди них исходный код NewRoute.dart выглядит следующим образом:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('新页面')
),
body: new Center(
child: new Text(
'点击浮动按钮返回首页',
),
),
floatingActionButton: new FloatingActionButton(
onPressed: () {
Navigator.of(context).pop();
},
child: new Icon(Icons.replay),
),
);
}
}
Новый маршрут наследуется от StatelessWidget, интерфейс очень прост, а в середине страницы отображается предложение «Это новый маршрут». Затем измените исходный код main.dart следующим образом:
import 'package:flutter/material.dart';
import 'package:flutter_demo/SecondPage.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: '路由管理首页'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Text(
'点击浮动按钮打开新页面',
),
),
floatingActionButton: new FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => SecondPage()));
},
child: new Icon(Icons.open_in_new),
),
);
}
}
Запустив приведенный выше код, когда мы нажмем кнопку, маршрутизация откроет новую страницу маршрутизации, как показано ниже:
MaterialPageRoute
MaterialPageRoute наследуется от класса PageRoute.Класс PageRoute представляет собой абстрактный класс, представляющий модальную страницу маршрутизации, занимающую все пространство экрана. Он также определяет связанные интерфейсы и свойства анимации перехода при построении маршрута и переключении. MaterialPageRoute – это виджет из библиотеки компонентов Material. Он может реализовывать анимацию переключения маршрутов, которая соответствует стилю анимации переключения страниц платформы для разных платформ. В частности:
- Для Android при открытии новой страницы новая страница перемещается из нижней части экрана в верхнюю часть экрана; когда страница закрывается, текущая страница перемещается из верхней части экрана в нижнюю часть экрана. экране, а затем исчезают, а на экране отображается предыдущая страница.
- Для iOS при открытии страницы новая страница будет перемещаться от правого края экрана к левому, пока вся новая страница не отобразится на экране, а предыдущая страница будет перемещаться с текущего экрана на слева от экрана и исчезают; когда При закрытии страницы происходит обратное, текущая страница выдвигается из правой части экрана, а предыдущая страница выдвигается из левой части экрана.
Когда мы используем MaterialPageRoute для завершения перехода по маршруту, конструктор MaterialPageRoute предоставляет несколько параметров в следующем формате:
MaterialPageRoute({
WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
})
Конкретные значения этих параметров следующие:
- builder — это функция обратного вызова типа WidgetBuilder, ее роль заключается в построении определенного содержимого страницы маршрутизации, а возвращаемое значение — это виджет. Обычно мы хотим реализовать этот обратный вызов, возвращая экземпляр нового маршрута.
- settings содержит информацию о конфигурации маршрута, такую как имя маршрута, является ли начальный маршрут (домашняя страница).
- maintenanceState: по умолчанию, когда новый маршрут помещается в стек, исходный маршрут все еще будет храниться в памяти.Если вы хотите освободить все ресурсы, занятые маршрутом, когда он бесполезен, вы можете установить дляmaintenanceState значение false.
- fullscreenDialog указывает, является ли новая страница маршрутизации полноэкранным модальным диалоговым окном.В iOS, если fullscreenDialog имеет значение true, новая страница будет скользить снизу экрана (а не горизонтально).
Navigator
Navigator — это виджет управления маршрутизацией в разработке приложений Flutter, который управляет коллекцией виджетов маршрутизации через стек. Обычно страница, отображаемая на текущем экране, является маршрутом вверху стека. Navigator предоставляет ряд методов для управления стеком маршрутизации.Мы можем использовать push и pop для отправки и извлечения страниц.
push
Поместите данный маршрут в стек (то есть откройте новую страницу), а возвращаемое значение — это объект Future для получения возвращаемых данных, когда новый маршрут будет извлечен (то есть закрыт).
При выполнении операции проталкивания мы в основном используем два метода: один — напрямую протолкнуть маршрут, а другой — протолкнуть Named именованный адрес маршрута.
метод проталкивания
Ниже приведен исходный код Navigator.push. Во входном объекте Route есть переменная-член RouteSettings. Мы можем поместить параметры для передачи в RouteSettings при построении объекта Route.
@optionalTypeArgs
static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}
Если дело доходит до передачи параметров, то мы можем поместить параметры в конструктор SecondScreen или в RouteSettings построенного MaterialPageRoute.
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondScreen()),
).then((data){
//接受返回的参数
print(data.toString());
};
метод pushNamed
Реализация метода pushNamed, наконец, вызывает метод push, который напрямую предоставляет аргументы параметра Object.Исходный код выглядит следующим образом:
@optionalTypeArgs
static Future<T> pushNamed<T extends Object>(
BuildContext context,
String routeName, {
Object arguments,
}) {
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}
@optionalTypeArgs
Future<T> pushNamed<T extends Object>(
String routeName, {
Object arguments,
}) {
return push<T>(_routeNamed<T>(routeName, arguments: arguments));
}
При использовании метода pushNamed маршрут необходимо прописать в таблице маршрутизации, например:
Navigator.of(context)
.pushNamed(
'/route1',
arguments: {
"name": 'hello'
}
).then((data){
//接受返回的参数
print(data.toString());
};
pop
POP Office POSS верхний маршрут стека, входной параметр является объектом объекта типа, а выходной параметр - это данные, возвращаемые на предыдущую страницу, когда текущая страница закрыта.
Поп-источник следующим образом:
@optionalTypeArgs
static bool pop<T extends Object>(BuildContext context, [ T result ]) {
return Navigator.of(context).pop<T>(result);
}
Использовать pop очень просто, например:
Navigator.of(context).pop(""); //可以传递参数
Чтобы перейти между двумя страницами, если это связано с передачей параметров, вы можете использовать следующие методы:
Navigator.of(context).pushNamed('/route1', arguments: {"name": 'hello'});
При получении параметров можно использовать следующие методы:
class Page extends StatelessWidget{
String name;
@override
Widget build(BuildContext context) {
dynamic obj = ModalRoute.of(context).settings.arguments;
if (obj != null && isNotEmpty(obj["name"])) {
name = obj["name"];
}
return Material(
child: Center(
child: Text("this page name is ${name}"),
),
);
}
}
именованный маршрут
Так называемый именованный маршрут заключается в том, чтобы дать маршруту имя, а затем вы можете напрямую открыть новый маршрут через имя маршрута. Это обеспечивает интуитивно понятный и простой способ управления маршрутом, который очень похож на путь, определенный инфраструктурой перехода на страницу ARrouter в Android.
Имена маршрутов по соглашению используют структуру, подобную пути, а домашний маршрут приложения по умолчанию имеет значение «/», например, «/home» для HomeScreen и «/login» для LoginScreen.
таблица маршрутизации
Чтобы использовать именованную маршрутизацию, мы должны сначала предоставить и зарегистрировать таблицу маршрутизации, чтобы приложение знало, какое имя соответствует какому виджету маршрутизации. Таблица маршрутизации определяется следующим образом:
Map<String, WidgetBuilder> routes;
Это карта, ключ — это имя маршрута, которое представляет собой строку, значение — это функция обратного вызова построителя, которая используется для создания соответствующего виджета маршрутизации. Когда мы проталкиваем новый маршрут через имя маршрута, приложение найдет соответствующую функцию обратного вызова WidgetBuilder в таблице маршрутизации в соответствии с именем маршрута, а затем вызовет функцию обратного вызова, чтобы сгенерировать виджет маршрута и вернуть его.
Например, у нас есть параметр конструктора маршрутов при создании MaterialApp:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: '应用程序首页'),
routes: <String, WidgetBuilder> {
'/a': (BuildContext context) => new MyPage(title: 'A 页面'),
'/b': (BuildContext context) => new MyPage(title: 'B 页面'),
'/c': (BuildContext context) => new MyPage(title: 'C 页面')
},
);
}
}
Зарегистрировать таблицу маршрутизации
Метод регистрации маршрута во Flutter относительно прост, вернемся к предыдущему «встречному» примеру, а затем найдем MaterialApp в методе сборки класса MyApp, добавим атрибут route, и код будет таким:
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context)=>NewRoute(),
} ,
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
Таким образом, используя маршруты, мы завершили регистрацию таблицы маршрутизации. Теперь мы можем открывать новые маршруты по имени маршрута. Формат перехода pushNamed следующий:
Future pushNamed(BuildContext context, String routeName,{Object arguments})
В дополнение к методу pushNamed в Navigator есть и другие методы управления именованными маршрутами, такие как pushReplacementNamed.Читатели могут самостоятельно просматривать документацию по API. Затем мы открываем новую страницу маршрутизации через имя маршрутизации и модифицируем код обратного вызова FlatButton onPressed:
onPressed: () {
Navigator.pushNamed(context, "new_page");
//Navigator.push(context,
// new MaterialPageRoute(builder: (context) {
// return new NewRoute();
//}));
},
именованный параметр маршрута
В начальной версии Flutter именованные маршруты не могли передавать параметры, а параметры стали поддерживаться позже. Например, ниже показано, как именованные маршруты проходят и получают параметры маршрута.Сначала зарегистрируйте маршрут:
routes:{
"new_page":(context)=>EchoRoute(),
} ,
Затем получите параметры маршрутизации через объект RouteSetting на странице маршрутизации, например:
class EchoRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
//获取路由参数
var args=ModalRoute.of(context).settings.arguments
//...省略无关代码
}
}
Затем передайте параметры при открытии маршрута:
Navigator.of(context).pushNamed("new_page", arguments: "hi");