Reputation: 23
I am trying to disable the back navigation when \_timerStarted
is true
or \_isBrushing
is true
.
This is my current implementation:
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) async {
// Allow pop only if the timer has finished or the user taps finishBrushing
if (_timerStarted || _isBrushing) {
// Show snackBar with 'Finish brushing to exit the screen'
return; // Prevent exiting the screen by not invoking the pop
}
final navigator = Navigator.of(context);
navigator.pop(result);
},
child: Scaffold(
...
)
);
This is perfectly working, but whenever the back option is working and I exit the screen, I get the error:
E/flutter ( 5204): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 5350 pos 12: '!_debugLocked': is not true. E/flutter ( 5204): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:50:61) E/flutter ( 5204): #1
_AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5) E/flutter ( 5204): #2 NavigatorState.pop (package:flutter/src/widgets/navigator.dart:5350:12) E/flutter ( 5204): #3 TimerScreenState.build. (package:toothbrush/timer.dart:594:21) E/flutter ( 5204): #4
PopScope._callPopInvoked (package:flutter/src/widgets/pop_scope.dart:137:30) E/flutter ( 5204): #5 _PopScopeState.onPopInvokedWithResult (package:flutter/src/widgets/pop_scope.dart:172:12) E/flutter ( 5204): #6 ModalRoute.onPopInvokedWithResult (package:flutter/src/widgets/routes.dart:1780:16) E/flutter ( 5204): #7 _RouteEntry.handlePop (package:flutter/src/widgets/navigator.dart:3171:11) E/flutter ( 5204): #8 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:4340:22) E/flutter ( 5204): #9 NavigatorState.pop (package:flutter/src/widgets/navigator.dart:5368:7) E/flutter ( 5204): #10 TimerScreenState.build. (package:toothbrush/timer.dart:594:21) E/flutter ( 5204): #11
PopScope._callPopInvoked (package:flutter/src/widgets/pop_scope.dart:137:30) E/flutter ( 5204): #12 _PopScopeState.onPopInvokedWithResult (package:flutter/src/widgets/pop_scope.dart:172:12) E/flutter ( 5204): #13 ModalRoute.onPopInvokedWithResult (package:flutter/src/widgets/routes.dart:1780:16) E/flutter ( 5204): #14 NavigatorState.maybePop (package:flutter/src/widgets/navigator.dart:5319:25) E/flutter ( 5204): E/flutter ( 5204): #15
WidgetsBinding.handlePopRoute (package:flutter/src/widgets/binding.dart:848:11) E/flutter ( 5204): E/flutter ( 5204): #16
MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:571:42) E/flutter ( 5204): E/flutter ( 5204): #17
_DefaultBinaryMessenger.setMessageHandler. (package:flutter/src/services/binding.dart:618:22) E/flutter ( 5204): E/flutter ( 5204):
Again, everything works as expected, but I would like to understand and fix this error as well. What can I do?
Upvotes: 1
Views: 81
Reputation: 832
As you can see in the onPopInvokedWithResult
documentation:
This will still be called even when the pop is canceled. A pop is canceled when the relevant
Route.popDisposition
returns false, such as whencanPop
is set to false on aPopScope
. ThedidPop
parameter indicates whether or not the back navigation actually happened successfully.
You should check the didPop
variable first before doing any other things in onPopInvokedWithResult
. I added the didPop
checking in your code:
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) async {
// Check if [didPop], then don't continue the process.
if (didPop) return;
// Allow pop only if the timer has finished or the user taps finishBrushing
if (_timerStarted || _isBrushing) {
// Show snackBar with 'Finish brushing to exit the screen'
return; // Prevent exiting the screen by not invoking the pop
}
final navigator = Navigator.of(context);
navigator.pop(result);
},
child: Scaffold(
...
)
);
Upvotes: 2