I'm working on a windows application with flutter desktop, for now, everything seems to work smoothly and with no problems.
But I suspect that I caused a memory leak when using PageView !!
Basically, I have PageViews with 6 pages. One of those pages is a form with a lot of TextEditingController and yea I'm calling dispose() for each TextEditingController and also for all BLoCs I'm using.
Now when The user submits the data and I get a reply from the API that the data was stored successfully I show a success dialog:
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Succès'),
content: Text(message),
actions: [
FlatButton(
child: Text('Sortie'),
textColor: Colors.white,
color: kColorGreen,
onPressed: () {
Navigator.of(context).pop();
pageController.jumpToPage(2);
// Tried calling dispose here !!
// dispose();
},
),
],
);
},
);
OnPressed: I take the user to another page. And it works BUT when I navigate back to the form page all the form fields are still filled with the old data and the dispose method never gets called !!
I tried calling the dispose method by myself before navigating to another page but no luck !!
So my question is: How can I dispose of all the TextEditingController and the BLoCs present on the form page when navigating out of it?
Related
I have 2 dart file. I want close the alertdialog from another dart file in specific conditions.
How can I ?
for example the function i want.(I wrote to express myself better.)
void example(){
if(control==false){
alertDialog.close();
}
Alert dialog file
class AlertForm extends StatefulWidget {
#override
_AlertFormState createState() => _AlertFormState();
}
class _AlertFormState extends State<AlertForm> {
void _showDialog() {
// flutter defined function
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Alert Dialog title"),
content: new Text("Alert Dialog body"),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
So what I want is to use the pop action in a function in another flutter file.
Call Navigator.of(context).pop(); inside the if block (of the void example function of the other Dart file) and the alert should close.
But here is the problem, the context above might not be part of or aware of the dialog and the above may not work.
More info about your setup would suggest a solution to this problem. Like how exactly does the other Dart file exist relative to the file where _showDialog is declared? If it's something you can easily provide context from AlertForm Dart file to the closingDialog Dart file, then you should know what to do. If that's not the case then a navigator key should help.
You can keep a navigator key for the entire application. Then instead of closing the dialog with Navigator.of(context).pop();, you use navigatorKey.currentState!.pop();.
You should have properly setup the navigator key yourself. Refer to this Stackoverflow answer for how to do that: https://stackoverflow.com/a/72945522/13644299
It is not compulsory to use get_it package. You can simply export the NavigationService (that will keep the navigatorKey) from any Dart file or with any method you deem fit, depending on your current state management architecture.
I am fairly new to state management in Flutter, and I have an application where the user will be interacting with dialogs, and a dialog may have a button to open another dialog which can result in the following:
https://i.stack.imgur.com/VBSzr.png
As shown, multiple issues arise when more than one is opened at once -- most notably the previous dialog is still visible in the background. So when a user opens a new dialog, is there any method where I can hide the dialog behind it, and when the frontmost dialog closes, show the previous one which is hidden? Thanks in advance.
Use Navigator.pop(context); method to close the dialog on your button's onPressed before opening the second dialog.
And then while closing your second dialog you can reopen your previous dialog.
Example:
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Hello World"),
content: Text("This is content"),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context); //Close your current dialog
//TODO:open your second dialog
},
child: Text("Open"))
],
);
});
I would first try to re-think the logic for opening multiple dialogs at the same time.
Maybe there is a quick workaround for that, but if you keep adding more and more dialogs, then it would become a mess.
Since showDialog<T> function returns Future<T?>, you could potentially use await and wait until the first dialog is closed and then open the second one and so on:
bool canContinue = await showDialog<bool>(
context: context,
builder: (context) => YourWidget(),
);
Alternatively, you could pop by using Navigator but as said, this will be visible to the user that something weird is going on (pushing and popping dialogs programatically).
I try to build a flutter app and want to navigate trough the pages.
I build a drawer with a menu with several items to open new pages - that works fine.
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) => new Page1(),
),
);
},
By pressing on the Page1 menuitem page1 opens fine.
Inside page1 I have a slidable list with "edit" and "details". I open this with
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => new DetailsPage(),
),
);
},
In the details Page I see all the things i wanna see, but when I press the Back button in the appBar i am back at home screen with closed drawer.
I tried to put onPressed: () => Navigator.pop(context); inside the appBar section but this doesn´t work either.
Now I got what I want by using always Navigator.push but I am sure that this is not right, so that navigator stack gets bigger and bigger.
What I do wrong? Why .pop does not bring me to the last page?
Any ideas?
Thx in advance
Patrick
Just remove the line with the Navigator.of(context).pop();in the Page1 onTap.
you can use pushReplacement in any cases you need to remove current page from stack and route to new page.
Replace the current route of the navigator that most tightly encloses
the given context by pushing the given route and then disposing the
previous route once the new route has finished animating in.
here is the documentation
Right now I am trying to delete data and when I am done delete it. It should be going to the homepage. The issue here is when I am using the navigator to the homepage. The user_id returns null instead of it should be showing the real user_id. How can I manage the flow of content?
Code that I use to go back 2 pages before.
new RaisedButton(
child: new Text("OK DELETE!",style: TextStyle(color: Colors.black),),
color: Colors.red,
onPressed: (){
deleteData();
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context)=> OwnerPage())
);
},
),
The image on before deleting occur:
The image on after deleting occur:
For additional information. From the login page to the home page, I am using this type of code:
If you are using routes to navigate between pages you can do this
Navigator.pushNamed(context,'/OwnerPage');
this will directly navigate to the OwnerPage
Hope this is helpful!
There are different approaches to navigate between pages. The bad one is, you can Navigator.pop() two times. The good one is, you need to add parameters:
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context)=> OwnerPage(username: username, user_id: user_id)) // Add parameters
);
I want to explain something in my app and add a widget which looks like a notification or chat. I want this widget to be visible for some time and then get dismissed. I tried using tooltip but it is visible only when I click it.
Which widget can I use?
The Dart package intro_views_flutter is what you need, but one of its main limitations is that it is displayed on full screen, if that is not an issue to you, then you should take a look at it. Or you can use a showDialog method inside a Future function this way :
Future showNotification() async {
showDialog<String>(
context: context,
child: new AlertDialog(
title: Text('Note!') ,
contentPadding: const EdgeInsets.all(16.0),
content: //any widget you want to display here
),
);
await new Future.delayed(const Duration(seconds: 5), () {
Navigator.of(context).pop(); // this will dismiss the dialog automatically after five seconds
}
}
then when you need it call:
showNotificaion();