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.
Related
I'm making an app with Dart/ flutter now and having an issue with routing pages.
The app is basically the matching app, and I want to add the functionality that a user can edit their profile. Currently, we have 4 stateful widgets: Match(), Message(), MyProfile() and EditProfile(). In the bottom navigation bar, I put three widgets, Match(), Message(), and MyProfile(); when the user wants to change the profile information, the person goes to MyProfile() and click "edit profile" button, which takes the user to EditProfile. After the user changes the information, I want to rout the page to MyProfile() for allow the user to check the profile info.
The code below is some part of the Navigation bar.
class _NavigationHomeState extends State<NavigationHome> {
int _currentIndex = 0;
final List<Widget> _children = [
Match(),
Messages(),
MyProfile(),
];
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
and I put the code below in one of the button of the EditProfile().
Navigator.of(context).pushNamed('/myProfile');
Then gave me an error saying
Error: Could not find the correct Provider above this
MyProfile Widget
This likely happens because you used a BuildContext that does not
include the provider of your choice. There are a few common scenarios:
The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route,
then other routes will not be able to access that provider.
You used a BuildContext that is an ancestor of the provider you are trying to read.
Make sure that MyProfile is under your
MultiProvider/Provider. This usually happen when you are
creating a provider and trying to read it immediatly.
I guess I'm getting this error because we set the _currentIndex in the bottom navigation bar as 0, which is Match(), so Navigator.of(context).pushNamed('/myProfile'); trying to take the user to the Match() page (?)
How can we take the user to the MyProfile page after the person save and click the button on EditProfile()?
Try using MaterialPageRoute instead of named routes.
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
If you going to EditProfile from MyProfile widget then I suggest to just pop the screen. As this will not reload complete screen, you can always pass data while doing pop.
RaisedButton(
onPressed: () {
// The Yep button returns "Yep!" as the result.
Navigator.pop(context, 'Yep!');
},
child: Text('Yep!'),
);
Another option is to use pushNamedAndRemoveUntil method.
navigator.pushNamedAndRemoveUntil('/MyProfile', ModalRoute.withName('/MyProfile'));
I guess I'm getting this error because we set the _currentIndex in the
bottom navigation bar as 0, which is Match(), so
Navigator.of(context).pushNamed('/myProfile'); trying to take the user
to the Match() page (?)
Not sure about your error but you can pass data as argument while doing pushNamed.
RaisedButton(
child: Text("Navigate to MyProfile"),
onPressed: () {
Navigator.pushNamed(
context,
'/myProfile',
arguments: [
'Extract Arguments Screen',
'This message is extracted in the build method.',
],
);
},
),
im completely new to flutter and im facing some issues rn , i have a textfield which i input in some string , then i save the input through the TextEditingController , i next want to display the input in another screen , but what's happening in my case that everytime i change screens the TextEdditingcontroller.text value gets reset ,
full code at : https://github.com/0x-xsh/studentchat/tree/master/lib
issue at https://github.com/0x-xsh/studentchat/blob/master/lib/NewProblem.dart in LINE 142 , it prints the input value in the console but sends a blank string to the new screen. so it returns an error when https://github.com/0x-xsh/studentchat/blob/master/lib/ProblemList.dart LINE 19 executes.
i tried to do a setState on Line 142 but same issue.
I would add a List<Problem> parameter to our ProblemList class.
We can then pass in this list when navigating to our ProblemList page and access it with the following:
class ProblemList extends StatefulWidget {
final List<Problem> pList;
const ProblemList({this.pList});
#override
ProblemListState createState() => ProblemListState();
}
class ProblemListState extends State<ProblemList> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("My Problems"),
leading: Icon(Icons.list),
),
body: Text(widget.pList[0].desc), //<-------- This is where you access the list
),
);
}
}
Line 142 becomes:
onPressed: () {
Problem problem = new Problem(problemDescription.text, problemDetails.text);
problems.add(problem);
print(problems[0].desc);
Navigator.push(context,
MaterialPageRoute(builder: (context) =>
ProblemList(pList: problems))); //<----- Passing the list to the class
},
You can't access the state of other page like you do in ProblemList.dart...
You'll need to pass the list as an argument to the ProblemList.
Try to declare a List<Problem> problems; inside the ProblemList class, add this variable to class constructor and send the list on NewProblem.dart, line 147.
Also, you code is a mess... The files have a name and the classes have another name.. Very confusing...
Always try to use the correct naming convention to your files and classes. This will help you and whoever is trying to help you :)
https://dart.dev/guides/language/effective-dart/style
When you have a better understanding of Flutter, I recommend you to learn about state management with Flutter.. There's a lot of ways. Take a look at some options and pick the one that better corresponds to your project needs...
This kind of a code structure question. I have two pages in my app page1 and page2. Page2 y irrelevant except that you can navigate from page1 to page2 and back to page1.
In page1 I use this plugin . It shows a dialog and you provide a call back with the selected language. I use a Stream because I have to load a predefined language from shared preferences which is async. My intention is to pass _lang to page2. The code as I have it is working as expected. But if you navigate back to page1 from page2 you get the default language because I didn't call setState. If I put a setState inside the callback the changes don't persist because the stream gets rebuild every time. And I cannot take the stream out if I want the default to show on start.
StreamBuilder(
stream: langStream.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
_lenguaje = snapshot.data;
return ListTile(
leading: Icon(Icons.language),
title: Text('${snapshot.data.name}'),
trailing: Text('Your Lang'),
onTap: () {
showLangPicker(
context,
(Language lang) {
_lang = lang;
langStream.update(lang);
},
);
},
);
} else {
return Container();
}
},
),
I'm in chicken-egg situation. Thanks.
You need to use some sort of state management. I would use provider. How you would accomplish this is you would have an app level Model that extends ChangeNotifier called languageModel or settingsModel. The model would look something like this:
class SettingsModel extends ChangeNotifier {
Language _lang;
Language get lang => _lang;
set lang(Language lang) {
_lang= lang;
notifyListeners();
}
}
Then in page two when you get your language just call:
Provider.of<SettingsModel>(context, listen: false).lang = yourSelected Language
Then in your ListView you can retrieve the language by the following:
calling Provider.of<SettingsModel>(context).lang or by using a Consumer Widget as shown in the first link.
I hope this helped, and you may need to do more research on state management with provider to implement this, but using some form of state management is the cleanest solution to your problem, so you are not working around the framework instead of letting it help you.
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();
I am starting to learn Flutter and am working on a Calculator app. When I want to prevent the user from some action (let's say divide by zero), I want to display a Dialog showing an error message. This requires a context, but when I pass context, this results in an error.
The examples that I have seen that do display an alert dialog all appear to be the result of a button being pressed, and this uses the context that is present when the app Widget is created. My situation is that the dialog is displayed outside the creation of the widget, and it appears that the context is not valid there.
How can I display a dialog as a result of an action taken by the user rather than the clicking a button within the Widget that has been created for the app? An example would be great.
The error that I am getting is as follows:
I/flutter ( 6990): The getter 'modalBarrierDismissLabel' was called on null.
While I presume from what I have read that I need to restructure the code and reposition the Alert Dialog, I have no idea how to do that. The examples that I have seen that work result from a Widget created on construction that consequently uses the context available at that point. In my case, I'm attempting to create the alert dialog as a result of an outcome from the result of what a user has done, not from the pressing of a widget button.
Some of my relevant code is as follows:
} else if (pendingOperator == "/") {
if (secondValue != 0) {
setNewValue(Decimal.parse(firstValue.toString()) /
Decimal.parse(resultString));
} else {
_showAlert(context, "Divide by zero is invalid");
}
}
class MyAppState extends State<MyApp> {
Decimal firstValue;
String pendingOperator;
bool clearCurrentValue = true;
String resultString = "0";
void _showAlert(BuildContext context, String text) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text("Error"),
content: Text(text),
));
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new SafeArea(
child: new Material(
color: Colors.black,
child: Column(
The need to show the alert is indirectly the result of a button being pressed. When that button is created, pass the context to the function that is called and use that context in the call to _showAlert.