I'm having trouble creating showDialog. I want to draw a dialog apo sample I have all the elements. But the problem is that I can't place them properly. Here's what I want to do:
enter image description here
I'm having trouble creating showDialog. I want to draw a dialog apo sample I have all the elements. But the problem is that I can't place them properly. Here's what I want to do:
There is text, an icon and a button. I created it all, but there is a problem with the display, it's not in the center. Here is my code, can anyone know how all this will lead to a normal look, I will be grateful.
_showDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext ctx) {
// return object of type Dialog
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
title: Center(child: Text(Titles.serviceNotAvailable)),
//content: const Text(Titles.serviceNotAvailable),
actions: <Widget>[
SvgPicture.asset(Img.simpleOrder),
CustomElevatedButton(
isDark: false,
isEnabled: false,
onPressed: () {
_showDialog(context);
},
child: Text(
Titles.backToChoiceServices,
style: TextStyle(
color: Colorz.primary,
fontSize: FontSize.small,
fontWeight: FontWeight.w600,
),
),
),
],
);
},
);
}
Trye to wrap it in a Center widget, setting it as his child.
Related
So I'm searching for a Menu often found in a Settings Screen. It's used to select a Setting.
It opens when you press on a ListTile and then it fills the mayority of the Screen, while the borders are transparent. In the menu you have to select one of the options.
An example usecase of that would be to select a Language(onTap of the ListTile opens a Menu where you can select between all the avaliable languages)
It is similar to that of a PopupMenuButton, however as already mentioned it fills most of the screen, and the individual selectable items have a radiobutton in front of the text(probably RadioListTiles)
I hope someone gets what I'm talking about, because for the past 3 hours I'm searching for this widget but just find articles about the PopupMenuButton over and over.
Edit: I finally found an app that uses the feature I'm looking for
: https://imgur.com/a/A9k71io
By clicking on the first ListTile in the first Picture, the dialog in the second picture opens up.
Hopefully this custom widget is something roughly what you want, try to copy and paste it in your project and play with it.
this is made using the Dialog widget, to exit the Dialog you can tap out of it/ press the device back arrow and I added a small back icon on the top left corner.
tell me if it helped :)
class TestPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final deviceSize = MediaQuery.of(context).size;// the device size
return Scaffold(
body: Center(
child: ListTile(
tileColor: Colors.grey[300],
title: Text(
'Language',
style: TextStyle(fontSize: 25),
),
onTap: () => showDialog(
context: context,
builder: (context) => Dialog(
insetPadding: EdgeInsets.all(20),
child: Container(
color: Colors.white,
height: deviceSize.height,
width: deviceSize.width,
child: Column(
children: [
Row(
children: [
IconButton(
color: Colors.red,
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
],
),
Spacer(),
Text('Pick A Language'),
Spacer(),
],
),
),
),
),
),
),
);
}
}
My requirement is something like this:
Flutter - change appbar icon when receiving notification
But AppBar 'cart icon' which is to be notified on 'addToCart' button click implemented in another dart file. Am I doing something wrong by placing the AppBar and the rest in two different dart files? Let me know how to proceed.
You can use a global ValueNotifier variable. Then you can change it's content regardless the page in which you are.
Assuming this variable declaration ValueNotifier cartCounterNotifier = ValueNotifier(0);, you can update your AppBar action like this
appBar: AppBar(
// title and other
actions: [
ValueListenableBuilder(
valueListenable: cartCounterNotifier,
builder: (context, cartCounter, child) {
return Stack(
children: [
IconButton(
icon: Icon(Icons.shopping_cart_rounded),
onPressed: () {},
),
Positioned(
child: 0 < cartCounter ? Container(
decoration: ShapeDecoration(
color: Colors.red,
shape: CircleBorder(),
),
padding: EdgeInsets.all(2.0),
child: Text("$cartCounter", style: TextStyle(
color: Colors.white,
),),
) : SizedBox(),
),
],
);
}
)
],
),
Update:
So to update your action button, simply change the content of your variable like this
cartCounterNotifier.value = cartCounterNotifier.value + 1; // or another value
I have a flutter web app. When I use it on my computer everything works fine. But if I use it on my phones browser parts of the Text are just missing. The Bounds of the text or the box dont matter, its just missing. Only if I press it, it shows the whole text. Has anyone an idea why that could be? Oh and when I shorten the text its the same. The last part is missing.
Already tried using FittedBox for the text but doesnt work. Thanks
Code for the alertBoxes:
void showCustomDialog(BuildContext context, String message) {
showDialog(
context: context,
child: AlertDialog(
title: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
message,
style: TextStyle(color: Colors.red),
),
),
actions: [
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Abbrechen",
style: TextStyle(color: Colors.red),
),
),
]));
}
First part of the dialog:
Widget dialog(BuildContext context) {
return AlertDialog(
title: Text("Kategorie Hinzufügen?"),
content: TextFormField(
controller: textEditingController,
decoration: InputDecoration(
labelText: "Namen eingeben",
prefixIcon: Icon(Icons.category_outlined)),
onChanged: (String val) {},
),
actions: [
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Abbrechen",
style: TextStyle(color: Colors.red),
),
),
I fixed it. Apparently it happens when I use DuckDuckGo. When I use Chrome everything is fine. But when you use DuckDuckGo the last character of the String or if you have spaces everything behind the last space gets cutted. Hm strange
The flutter team just fixed it on the master channel (1.26.0-2.0.pre.403). I have tested it and it works fine. Probably soon it will be on the beta channel.
https://github.com/flutter/flutter/issues/65099
Widget build(BuildContext context) {
print("homepage");
final navigation = Provider.of<NavigationProvider>(context, listen: false);
return Consumer<ThemeProvider>(builder: (context, themeData, _) {
return Scaffold(
backgroundColor: themeData.getTheme['mainBackground'],
appBar: AppBar(
backgroundColor: themeData.getTheme['appBar'],
elevation: 0.0,
title: Text(
"INTRADAE",
style: GoogleFonts.montserrat(
color: themeData.getTheme['textColor'],
),
),
actions: <Widget>[
Container(
margin: EdgeInsets.only(right: 5),
child: IconButton(
icon: Icon(
Icons.account_balance_wallet,
size: 30,
color: themeData.getTheme['textColor'],
),
onPressed: null,
),
)
],
),
body: Consumer<NavigationProvider>(
builder: (context, navigationProvider, _) =>
navigationProvider.getNavigation),
bottomNavigationBar: CurvedNavigationBar(
index: 0,
height: 50,
color: themeData.getTheme['secondaryBackground'],
backgroundColor: themeData.getTheme['mainBackground'],
buttonBackgroundColor: themeData.getTheme['mainBackground'],
items: <Widget>[
Icon(Icons.home, color: Colors.white),
Icon(Icons.shopping_cart, color: Colors.white),
Icon(Icons.person, color: Colors.white)
],
onTap: (index) {
navigation.updateNavigation(_pages[index]);
},
),
);
});
I am trying to update whatever is inside the body of the scaffold when updateNavigation takes place. Everything seemed fine, until I put a print inside the build method of the main widget and noticed that it was being called on every update the to NavigationProvider.
I am scratching my head since. I can't understand why this widget has to rebuild when only the Consumers should rebuild which in this case is inside the body of the Scaffold.
Coming from a React background this just seems weird to me.
Can anyone tell me why this is happening?
The problem was solved once I performed a hot restart. I then read about Hot Reload in Flutter the docs and realised that the changes I was making to the code weren't going to be seen unless I performed a hot restart.
Although the code posted here has
listen:false
in,
Provider.of<NavigationProvider>(context, listen: false)
But, I originally did not have that in my code. And when adding that argument too didn't seem to help, I decided to post a question here.
The problem was hot reload all along. Should've have made sure before posting.
I have a home screen with a FAB and when it's pressed I want to display a dialog for user to input.
Currently I am using showDialog() with SimpleDialog.
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
title: NormalText('New Counter Item'),
contentPadding: EdgeInsets.fromLTRB(24.0, 0.0, 24.0, 24.0),
children: <Widget>[
Container(
...
)
],
);
}
);
But, I can't seem to customise almost anything with it (smaller, corner-curved and positioned lower on the screen). AlertDialog seems to be the same.
Is there anyway to customise those attributes?
return showDialog<void>(
barrierDismissible: true,
context: context,
builder: (BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(0),
child: new Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.purple,
child: new Column(
children: <Widget>[
new Text(
'custom dialog text',
style: new TextStyle(
fontSize: 14,
color: Colors.white,
),
),
],
),
),
)
],
);
},
);
hope this helps,
thanks
SimpleDialog and AlertDialog are meant to cater to a specific set of needs. They have certain levels of customization, but ultimately they are meant to just show simple pop-up dialogs that give the user some information and prompt for a dialog response (i.e. "Yes", "No", "Cancel", "Save", etc.).
If you want to have a more customizable pop-up dialog, you will need to create your own. On the plus side, though, it's really quite simple. Have the builder in showDialog return a Dialog widget with a child set to whatever you want:
showDialog(
context: context,
builder: (BuildContext cxt) {
return Dialog(
child: Container(
...
),
);
},
);
Obviously you are going to need to recreate things like the title bar and action bar, but you can either crack open the source code of SimpleDialog and AlertDialog and copy what they have there or you can roll your own solution.
Despite what the accepted answer says; there are ways to customise the SimpleDialog in the ways that you have requested.
Size
The SimpleDialog will grow in width/height depending on the child and how it is padded. The below code will generate a dialog of width 336 and height 300:
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
insetPadding: EdgeInsets.zero,
titlePadding: EdgeInsets.zero,
contentPadding: EdgeInsets.zero,
children: [
Container(
width: 300,
height: 300,
),
],
);
},
);
Not sure what the added 36 pixels to the width is; but this demonstrates that size can be customised.
Corners
Corners can be customised using the shape property. The below code shows a green border with a rounded edge of 4 pixels:
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4.0),
side: BorderSide(
color: Colors.green,
),
),
/* ... */
);
},
);
Position
I've found that I can nudge the dialog up and down the page by using the insetPadding property. This defines the minimum amount of space required between the edge of the screen and the dialog. Although it's a bit cumbersome, if you knew the size of the screen and the size of the dialog, you could nudge the dialog's position with some simple math.
Given a screen height of 1920px, and a dialog height of 300px, the below code should place your dialog 100px from the top edge of your screen, rather than bang in the centre:
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
insetPadding: EdgeInsets.only(bottom: 1520),
/* ... */
);
},
);
This is because I've requested a minimum padding between the bottom edge of the screen and the dialog; and the only position for the dialog to exist under this stipulation is nearer the top.
No. These are not designed to be customizable. They were made to respect Material Design principles in mind.
If you want a custom design, you can make your own modal based of Align and/or DecoratedBox
It's not as scary as you might expect.
You only need to clone Dialog.dart, and
replace the Center widget with an Align.
Of course also rename stuff; e.g. MyDialog, myShowDialog, MySimpleDialog.
Yep, it's that easy.
And if you're on a roll, how about adding the Align widget's alignment parameter as an extra...
You can actually modify it's position (only height) by adding a SingleChildScrollView() in the builder + a padding (for the offset from the top) as follows:
showDialog<String>(
context: context,
builder: (ctxDialog) =>
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(top: 150.0),
child: AlertDialog()
)
)
);
Here is a clean solution, If for some reason you have a TextField/TextFormField and in there you have a onsubmit property then you can follow:
onSubmit: () {
showDialog(
context: context,
builder: (context){
return WillPopScope(
onWillPop: () { return Future(() => false); }, // this will prevent going back
child: AlertDialog(
content: Row(
children: [
progressWidget(),
Container(margin: EdgeInsets.only(left: 10.0),child:Text("Loading" )),
],),
)
);
}
);
yourCallToMethod.whenComplete((){
Navigator.of(context).pop();
});
},
BENEFIT?
When the showAlert is shown if someone tap on the screen randomly or aggressively then the screen goes back. This prevents that behavior and only closes the showAlert when your function completes.
:- we can change vertical position of dialog boxes by give bottom
insetPadding like
insetPadding: EdgeInsets.only(bottom: XX);
:- And horizontal position by Horizontal padding or left
insetPadding: EdgeInsets.symmetric(horizontal:XX);
or
insetPadding: EdgeInsets.only(left: XX,right:YY);
I found the answer to it here. Thanks to #CopsOnRoad
Using showGeneralDialog
Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
showGeneralDialog(
context: context,
barrierColor: Colors.black54,
barrierDismissible: true,
barrierLabel: 'Label',
pageBuilder: (_, __, ___) {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
color: Colors.blue,
child: FlutterLogo(size: 150),
),
);
},
);
},
),
)
Solved that with wrapping dialog body in Stack and Positioned
Stack(
children: [
Positioned(
left: 100, // left coordinate
top: 100, // top coordinate
child: YOUR_DIALOG....