[Flutter combat] Detailed routing stack

Suppose there are two pages A and B. There is a button in A. Click to jump to page B. The code of page A:

class APage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: RaisedButton(
child: Text(‘A 页面’),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return BPage();
}));
},
),
);
}
}
B 页面代码:

class BPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: RaisedButton(
child: Text(‘B 页面’),
onPressed: () {

      },
    ),
  ),
);

}
}

When the application is on page A, there is only A in the routing stack, click the button to jump to page B, there are B and A in the routing stack, and B is at the top of the stack.

Click the button on page B to return to page A, modify the button click event on page B:

RaisedButton(
child: Text('B page'),
onPressed: () { Navigator.of(context).pop(); }, ) Changes in routing stack:



The effect of the above case is to jump from page B to page A, can the push method also be used? Modify B page button click event:

RaisedButton (
Child: the Text ( 'page B'),
onPressed: () { Navigator.of (context) .push (MaterialPageRoute (Builder: (context) { return APAGE (); })); }, ) In effect You can also jump to page A, routing stack:





Is it possible to use push instead of pop? The answer is definitely no,

Imagine the following scenario, enter the shopping App, display the shopping list, click on one of them to enter the product detail page, use push to enter the shopping list again, and then enter the product detail page... Repeatedly, a large number of shopping lists and products will be stored in the routing stack The detailed page routing, click the back button, will repeatedly display the shopping list and product detail page.
The routing animation push and pop are different when switching pages.
In the
above cases of maybePop and canPop, what happens if I click the A page button to directly call pop?

RaisedButton(
child: Text('A page'),
onPressed: () { Navigator.of(context).pop(); }, ) In page A, there is only A in the routing stack. After calling pop, the routing stack changes:



At this time, the routing stack is empty, there is no page to display, the application will exit or a black screen, a good user experience should not be like this, you can use maybePop at this time, maybePop will only pop up the route when there is a pop-up route in the routing stack.

The above case executes maybePop on page A:

RaisedButton(
child: Text('A page'),
onPressed: () { Navigator.of(context).maybePop(); }, ) After clicking, there will be no pop-up route, because there is only A in the current routing stack, which is in page B Executing maybePop will return to page A.



You can also use canPop to determine whether you can pop currently:

RaisedButton(
child: Text('B page'),
onPressed: () { if(Navigator.of(context).canPop()){ Navigator.of(context).pop(); } }, ) pushNamed pushNamed is named The routing method needs to configure the routing name in MaterialApp:






MaterialApp(
title: ‘Flutter Demo’,
routes: <String, WidgetBuilder>{
‘/A’: (context) => APage(),
‘/B’: (context) => BPage(),
},
home: Scaffold(
body: APage(),
),
)
从 A 跳转到 B:

RaisedButton(
child: Text('A page'),
onPressed: () { Navigator.of(context).pushNamed('/B'); }, ) pushReplacementNamed and popAndPushNamed have three pages A, B, C, page A Jump to B through pushNamed:




RaisedButton(
child: Text('A page'),
onPressed: () { Navigator.of(context).pushNamed('/B'); }, ) B Jump to C via pushReplacementNamed:



RaisedButton(
child: Text('B page'),
onPressed: () { Navigator.of(context).pushReplacementNamed('/C'); }, ) Click the C page button to execute pop:



RaisedButton(
child: Text(‘C 页面’),
onPressed: () {
if(Navigator.of(context).canPop()){
Navigator.of(context).pop();
}
},
)

Clicking the C page button directly returns to page A instead of page B, because page B uses pushReplacementNamed to jump, and the routing stack changes:

Jump from page B to page C and use popAndPushNamed:

RaisedButton(
child: Text('B page'),
onPressed: () { Navigator.of(context).popAndPushNamed('/C'); }, ) popAndPushNamed routing stack and pushReplacementNamed are the same, the only difference is that popAndPushNamed has B Page exit animation.



popAndPushNamed and pushReplacementNamed make the current page not in the routing stack, so this page cannot be returned through pop.

Applicable scene:

Welcome page: After the application is opened, first enter the welcome interface, and then enter the homepage. After entering the homepage, you should not enter the welcome interface again.
Login page: After successful login, enter the relevant page. Press the back button at this time, and you should not enter the login page again.
PushNamedAndRemoveUntil
has the following scenarios. The application enters the home page, clicks to log in to enter the login page, then enters the registration page or the forgotten password page..., after successful login, enters other pages. At this time, you do not want to return to the login related page. You can use pushNamedAndRemoveUntil in this scenario.

There are four pages A, B, C and D. A enters page B through push, B enters page C through push, and page D enters through pushNamedAndRemoveUntil. At the same time, delete the route until /B in the routing stack. The code of page C:

RaisedButton(
child: Text('C page'),
onPressed: () { Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/B')); ), ), D page button execution pop:



RaisedButton(
child: Text(‘D 页面’),
onPressed: () {
Navigator.of(context).pop();
},
)

Change of routing stack from page C to page D:

Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/B'));
means to jump to page D, and delete all routes from D to B directly. If you delete all routes, only save D :

Navigator.of(context).pushNamedAndRemoveUntil('/D', (Route route)=>false);
Routing stack changes:

PopUntil
has the following scenarios. When entering a new company, you need to fill in various information. The information is divided into different parts, such as basic information, work information, family information, etc. These different modules are on different pages. You can return to the previous one when filling in the information. Page, you can also cancel, cancel to return to the home page, this scene can use popUntil to pop to the specified page.

There are four pages A, B, C, and D. Page D is returned to page A through popUntil. The code of page D:

RaisedButton(
child: Text(‘D 页面’),
onPressed: () {
Navigator.of(context).popUntil(ModalRoute.withName(’/A’));
},
)

Routing stack changes:

Transfer data
There are the following scenarios, the product list page, click to jump to the product detail page, the product detail page requires the unique id of the product or product detail data, there are two ways to transfer data:

The first: through the constructor:

class ProductDetail extends StatelessWidget {
final ProductInfo productInfo;

const ProductDetail({Key key, this.productInfo}) : super(key: key);

@override
Widget build(BuildContext context) { return Container(); } } Jump code:



Navigator.of(context).push(MaterialPageRoute(builder: (context){ return ProductDetail(productInfo: productInfo,); })); This method cannot be used to name the route jump method.


The second way: setting parameters by named route:

A page transmits data,

RaisedButton(
child: Text('A page'),
onPressed: () { Navigator.of(context).pushNamed('/B',arguments:'from A'); }, ) B page through ModalRoute.of(context ).settings.arguments receive data:



RaisedButton(
child: Text(’${ModalRoute.of(context).settings.arguments}’),
onPressed: () {
Navigator.of(context).pushNamed(’/C’);
},
)

Return
code of page B:

RaisedButton(
child: Text('$(ModalRoute.of(context).settings.arguments)'),
onPressed: () { Navigator.of(context).pop('Return from B'); }, ) A page received Data returned:



class APage extends StatefulWidget {
@override
_APageState createState() => _APageState();
}

class _APageState extends State {
String _string = ‘A 页面’;

@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: RaisedButton(
child: Text(_string),
onPressed: () async {
var result =
await Navigator.of(context).pushNamed(’/B’, arguments: ‘来自A’);
setState(() {
_string = result;
});
},
),
),
);
}
}
亚马逊测评 www.yisuping.com

Guess you like

Origin blog.csdn.net/weixin_45032957/article/details/108616245
Recommended