When i swipe back, if nothing is changed it should just go back. if i have changed some personal data (for example, first name or last name) and I swiped back, it should stay in PersonalDataScreen and show ShowDialog.showDialogOnScreen()
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false, // I tried use here canPopMethod() below, but this isn't working
child: Scaffold(
appBar: CustomAppBar2(
title: 'Personal data',
onTapBack: () {
isProfileLoadedSuccesfully && hasChanges(profileModel)
? ShowDialog.showDialogOnScreen(
context: context,
title: 'Has changes, do you want to save?',
onTapNo: () {
Navigator.pop(context);
Navigator.pop(context);
},
onTapYes: () {
Navigator.pop(context); //close showDialog
Navigator.pop(context); //go back
changeProfile();
})
: Navigator.pop(context);
},
),
body: BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) {
isProfileLoadedSuccesfully = false;
return switch (state) {
ProfileInitial() => Center(child: CircularProgressIndicator()),
ProfileLoaded() => _buildBody(state, context),
};
},
),
),
);
}
Widget _buildBody(ProfileLoaded state, BuildContext context) {
isProfileLoadedSuccesfully = true;
return someWidget();
}
bool canPopMethod() {
if (isProfileLoadedSuccesfully == false) {
return true;
}
if (hasChanges(profileModel)) {
ShowDialog.showDialogOnScreen(
context: context,
title: 'Has changes, do you want to save?',
onTapNo: () {
Navigator.pop(context); //close showDialog
Navigator.pop(context); // go back
},
onTapYes: () {
Navigator.pop(context); //close showDialog
Navigator.pop(context); //go back
changeProfile();
},
);
return false;
}
return true;
}
bool hasChanges(ProfileModel? profileModel) {
return firstNameController.text != profileModel?.firstName ||
lastNameController.text != profileModel?.lastName ||
phoneController.text != profileModel?.phone ||
emailController.text != profileModel?.email ||
innPassportController.text != profileModel?.innPassport;
}
I tried use method in canPop: canPopMethod() but it doesn’t working. I think canPopMethod() works only one time when i opened PersonalDataScreen, and not working every time when i swipe back.
2
Answers
I did some research. I don't know if this is right way, but it worked for me. If you have another variants. I will appreciate it.
There has been some inconsistent behavior from PopScope and navigation. Table here explains it better. Note that ‘Expected’ column states if behavior is expected or not rather than expected value.
For best practice it’s good to use onPopInvoked for most consistent behavior of your app while this problem is not fixed. Couple things to keep in mind is downgrading your navigation, for example GoRouter 12.0.0 with code provided below works fine and stops all popping from the page. Easy work around would be using GestureDetector to see which way you are swiping and adding in the onPopInvoked your logic how you want to handle that. This code here is only to showcase how it works
Edit: Flutter version 3.22.1 is used here
Table with CanPop bahavior