want to launch URL in ELEVATEDBUTTON. there are too many button for launch too many URL how can I do this in flutter??
I can't understand how can I do this. can anyone solve this problem
you can map the list while rendering on ui.
...urlList
.map(
(e) => ElevatedButton(
onPressed: () {
launchUrl(Uri.parse(e)); //use .tryParse
},
child: Text("$e"),
),
)
.toList(),
You may create a model class with label and string url.
Related
TL;DR: Trying to pass a function call to a custom AlertDialog. AlertDialog needs to be popped after the function -> can't make it work.
I've created a custom AlertDialog to use throughout my app. It looks something like this:
customAlertDialog({required context, buttonAction}){
showDialog(context: context, builder: (context) => AlertDialog(
title: Text("example title", style: TextStyle(color: AppTheme.colors.white),),
content: const Text("some content"),
actions: [
TextButton(onPressed: () {Navigator.of(context).pop();}, child: Text(
"Abbrechen",
style: TextStyle(
color: AppTheme.colors.white),
),),
TextButton(
child: Text("do something",
style: TextStyle(
color: AppTheme.colors.lightRed),
),
onPressed: buttonAction)
],
),);
}
The customAlertDialog takes a function call as an argument (here named buttonAction) for the last TextButtons onPressed action. It works fine when I pass:
buttonAction: () => deleteUser(context)
The problem is that this does not work in combination with a pop method. In the following only deleteUser will be called:
buttonAction: () => [deleteUser(context), Navigator.of(context).pop()]
the same if written like this:
buttonAction: () {deleteUser(context), Navigator.of(context).pop()}
I guess that the context of the customAlertDialog itself needs to be popped. So I've tried the following in the customAlertDialog (buttonAction contains () => deleteUser(context):
onPressed: () => [buttonAction, Navigator.of(context).pop()]
Now it only pops the dialog, probably because dart cannot interpret the buttonAction. So I've searched to find a way to pass only the function that should be called but wasn't successful doing so.
So my question is: How can I pass a function and still pop the dialog?
EDIT:
As #SlowDeepCoder mentioned the problem could have been that the Navigator.pop() method throws the context from the stack before deleteUser() has finished and therefore it doesn't work. It was tried to be fixed with the following but it did not work:
buttonAction: () async{ await deleteUser(context); Navigator.of(context).pop(); }
This is because you call pop() on a Navigator from an incorrect BuildContext. So instead of
buttonAction: () {
deleteUser(context);
Navigator.of(context).pop();
}
you have to do something like this:
buttonAction: (innerContext) {
deleteUser(innerContext); // not sure if you need the innerContext here. Depends on your other app code
// deleteUser(context); // use this line if the above does not work
Navigator.of(innerContext).pop();
}
together with
TextButton(
child: Text("do something"),
onPressed: () => buttonAction(context),
)
I also would recommend you to give bot of your BuildContexts (customAlertDialog and showDialog) different names.
You do not always have to use arrow function to pass a custom function.
You can simply pass the function as
buttonAction: (){
deleteUser(context);
Navigator.of(context).pop();
}
My problem is simple. I was building a ListTile from the list of documents I get from firebase by iterating through the results. The ListTile contains a leading icon, a title, and a trailing favorite IconButton. The list tile shows perfectly as I want it to. But the problem arises when I try to change the color of the IconButton while a user taps on it. For some reason, the code I wrote isn't doing the trick. What i tried to do was to set the value of the IconButton's color by a ternary which uses a class variable named isFavorited. What i wanted it to do is change the color of the IconButton when i tap on that same IconButton. Here is my code block:
// Builds a tile for each brought up names of taxistops
if (retrievedData.isNotEmpty) {
retrievedData.forEach((element) {
if (element.contains(query) ||
element.contains(query.toUpperCase()) ||
element.contains(query.toLowerCase())) {
ListTile listTile = ListTile(
leading: Icon(Icons.local_taxi),
title: Text(element),
trailing: IconButton(
icon: isFavorited
? Icon(
Icons.star,
color: Colors.amber[400],
)
: Icon(Icons.star_border),
onPressed: () => {
setState(() {
isFavorited = true;
}),
addToFavorite()
},
),
onTap: () => close(context, element),
);
searchedTiles.add(listTile);
}
});
}
Any help is appreciated! Thank you in advance!
I think the problem is because you are adding the widget in the list you should preview it directly inside the widget father (ListView) so it can do the setState correctly and not inside a list you created as a data structure to store elements.
I think that's the issue if it still doesn't work I would need to see how you are showing the list.
I have the following flow Screen 1 -> Screen 2 -> Dialog (in a separate widget).
Screen 2 displays a dialog (Close? Yes or No). If someone presses Yes, I would like to return to the Screen 1, if they press No, just close the dialog and return to Screen 2. What I currently do is when Yes is tapped, I do Navigator.pop(context) twice. Is this a good practice? Is there a way to pass the context of Screen 2 to my dialog widget so I can pop that one directly?
Personally, I think it would be better to pass the response from the dialog back to the page, and let the page handle the rest.
You can do this:
//I'm using a raised button just to call the alert as an example...
RaisedButton(
child: Text('Press me'),
//This part here is the important part
onPressed: () async {
//You can return anything when you use Navigator.pop
//In this case I'm returning a bool indicating if the page should close or not.
//You have to await this because it depends on user input.
bool shouldPopResult = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
//The content of your dialog
actions: <Widget>[
// The value you pass here in Navigator.of(context).pop
// is the value that will be stored in shouldPopResult,
// so if "Yes" is pressed, true will return...
// and if "No", false is returned.
FlatButton(
child: Text('Yes'),
onPressed: () => Navigator.of(context).pop(true),
),
FlatButton(
child: Text('No'),
onPressed: () => Navigator.of(context).pop(false),
)
],
),
);
// This is for if the user dismisses the dialog without pressing a button
// In that case shouldPopResult would be null, so I'm setting it to false.
// You can prevent the user from dismissing the dialog
// setting barrierDismissible to false in the showDialog method.
if (shouldPopResult == null) shouldPopResult = false;
// And finally with the dialog already dismissed, you can decide
// to go back or not.
if (shouldPopResult) Navigator.of(context).pop();
});
As usual you can extract the dialog as a Widget, or extract the function that handles the dialog response altogether or anything else.
You can see the example of returning data from a page in the flutter documentation here.
Example
How to open the url together with the snackbar in One button?
onTap: () => launch("http://flutter.dev"),
// when button tapped then url will be open and displaying a snackbar at a time
Discard the arrow function and write it like this
onTap: (){
launch("http://flutter.dev");
Scaffold.of(context).showSnackBar(SnackBar(content: Text("Message here"),));
},
onTap: () {
firstFunction();
secondFunction();
},
Please comment if I misunderstood your question.
This is my home page code:
routes: {
'/second' : (context) => addExpence(),
},
my second-page code is:
FlatButton(
child: Text("Done".toUpperCase()),
onPressed: (){
Navigator.pop(context);
},
)
please note that both pages are in different files. Now the problem is that I am getting a black screen when popping from the First Page.
It's a natural thing to get a black screen when you pop from the first page because the Navigator will be empty. The only reason you're popping the first page is probably to close your app, for which you should use this method.
#Lewis Weng's answer is the correct one that works for me too.
if(Navigator.canPop(context)){
Navigator.of(context).pop();
}else{
SystemNavigator.pop();
}