Describe the bug
Using the Login tutorial, after navigate to another page using pushReplacementNamed, the _AppState BlocBuilder builder function was not called when I dispatch a new state from the new Page.
To Reproduce
Steps to reproduce the behavior:
authenticationBloc.dispatch(LoggedOut()); using the global AuthenticationBloc;Expected behavior
From new page dispatch LoggedOut and change the MaterialApp home to LoadingIndicator and LoginPage after;
Additional context
I'm using the last version ^0.5.3 and testing in iOS simulator.
This is because you are pushing a replacement so you are replacing everything with your new page and there is no _RootPage widget to be rebuilt.
I believe you鈥檇 get the expected behavior by just pushing and then calling pop before dispatching LoggedOut.
Does that help?
So, how do I avoid this? I already have put whole MaterialApp in the builder function but it doesn't work.
I have used the listen function to avoid BlocBuilder but without success.
I'm not sure I understand exactly what you want but you can do something like:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => OtherPage(),
),
);
},
)
],
),
body: Container(
child: Center(
child: Text('Home'),
),
),
);
}
}
class OtherPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final AuthenticationBloc authenticationBloc =
BlocProvider.of<AuthenticationBloc>(context);
return Scaffold(
appBar: AppBar(
title: Text('Other Widget'),
),
body: Container(
child: Center(
child: RaisedButton(
child: Text('logout'),
onPressed: () {
Navigator.popUntil(context, (ModalRoute.withName('/')));
authenticationBloc.dispatch(LoggedOut());
},
),
),
),
);
}
}
Using your example, I want avoid the use to press the back button and go back to HomePage. Your example just pop when the use press the button. I want remove the back button from app bar too.
I can achive all things using pushReplacement
You can't use pushReplacement because, like I said, it will replace everything you currently had rendered with your new Route so then the changes in AuthenticationState will have no impact.
To achieve what you want you can modify the above code to:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_login/authentication/authentication.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => OtherPage(),
));
},
)
],
),
body: Container(
child: Center(
child: Text('Home'),
),
),
);
}
}
class OtherPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final AuthenticationBloc authenticationBloc =
BlocProvider.of<AuthenticationBloc>(context);
return Scaffold(
appBar: AppBar(
leading: Container(),
title: Text('Other Widget'),
),
body: Container(
child: Center(
child: RaisedButton(
child: Text('logout'),
onPressed: () {
Navigator.popUntil(context, (ModalRoute.withName('/')));
authenticationBloc.dispatch(LoggedOut());
},
),
),
),
);
}
}
You can hide the back button by passing Container() as the leading in the AppBar.
Does that answer your question?
Closing this for now but feel free to comment and I鈥檒l reopen it.
Navigator.popUntil(context, (ModalRoute.withName('/'))); did it for me, thanks!
Here's a solution that worked for me to hide the back button and prevent moving back conditionally.
WillPopScope(
onWillPop: () async => false,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
)))
Most helpful comment
You can't use
pushReplacementbecause, like I said, it will replace everything you currently had rendered with your new Route so then the changes inAuthenticationStatewill have no impact.To achieve what you want you can modify the above code to:
You can hide the back button by passing
Container()as the leading in theAppBar.Does that answer your question?