Open e200 opened 3 years ago
Hi @e200 👋 Thanks for opening an issue!
This is working as expected because your FlowBuilder is a disconnected flow so the first page doesn't know about where it came from and whether it should show a back button.
You can add a BackButton
as needed to the first page:
Scaffold(
appBar: AppBar(
leading: BackButton(onPressed: () => context.flow<MyFlowState>().complete(),
...
),
...
)
Hope that helps 👍
This makes all sense.
But if FlowBuilder provided a way to toggle this option, would be really useful because not every flow may require the button to be visible (hard coded). What do you think?
I agree with @e200. The FlowBuilder
or FlowController
could have a field allowPop
.
Agree on this. I would prefer not to add navigation logic in my screen because it limits the usecases of the screen and how it can be built. I think the allowPop would be a nice addition.
For this case we use this workaround:
class FlowPage<T> extends Page<T> {
const FlowPage({
required this.child,
this.maintainState = true,
this.onPop,
super.key,
super.name,
super.arguments,
super.restorationId,
});
final Widget child;
final bool maintainState;
final void Function(BuildContext context)? onPop;
@override
Route<T> createRoute(BuildContext context) {
return _PageBasedFlowPageRoute<T>(page: this);
}
}
class _PageBasedFlowPageRoute<T> extends PageRoute<T>
with MaterialRouteTransitionMixin<T> {
_PageBasedFlowPageRoute({
required FlowPage<T> page,
}) : super(settings: page) {
assert(opaque);
}
FlowPage<T> get _page => settings as FlowPage<T>;
@override
Widget buildContent(BuildContext context) {
if (_page.onPop != null) {
return WillPopScope(
child: _page.child,
onWillPop: () async {
_page.onPop?.call(context);
return true;
},
);
}
return _page.child;
}
@override
bool get willHandlePopInternally => _page.onPop != null;
@override
bool get maintainState => _page.maintainState;
@override
String get debugLabel => '${super.debugLabel}(${_page.name})';
}
Now we can add onPop handler to FlowPage:
onGenerateRoutes(state, pages) {
return [
FlowPage(
onPop: (context) => context.flow<RegistrationFlowState>().complete(),
child: FirstPageInStack(),
),
// ....
];
}
Back button appears automatically because willHandlePopInternally
flag is set while onPop
handler provided. Hope this helps someone.
This workaround breaks iOS pop gestures: https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/cupertino/route.dart#L194
Describe the bug The back button is not visible for the first page, it's only visible for the second and up
To Reproduce Steps to reproduce the behavior: With this
Flow
widget you will see the issue:Expected behavior The arrow button to be visible for wach flow state.
Screenshots
https://user-images.githubusercontent.com/20504726/108818386-925e8680-75b9-11eb-9c85-56f6d24373e6.mp4
Logs Run
flutter analyze
and attach any output of that command below.Paste the output of running `
flutter doctor -v` here.
Additional context:
Incredibly the same doesn't happen if we add another empty page before the others:
I think the problem is with the code that checks the length of pages, I'm not sure.