I want to show dialog when I press the button I want to be navigated to another page and then I want to show a dialog indicating that I have been navigated to that page.
So I try this code;
InkWell(
onTap: () async {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => BottomBarD()),
(route) => false);
Dialog(
child: Container(
child: Column(
children: [
Text(
"Navigated to Another Page",
style: TextStyle(
fontFamily: "Quando",
fontWeight: FontWeight.w500,
fontSize: 15,
),
),
TextButton(
onPressed: () async {
Navigator.of(context).pop();
},
child: Text(
"Okey",
style: TextStyle(
fontFamily: "Quando",
fontSize: 15,
),
),
),
],
),
),
);
},
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.orangeAccent, Colors.red],
begin: Alignment.bottomRight,
end: Alignment.centerLeft),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(112.0),
topLeft: Radius.circular(112.0),
bottomRight: Radius.circular(112.0),
topRight: Radius.circular(112.0),
),
),
height: MediaQuery.of(context).size.height * 0.065,
width: MediaQuery.of(context).size.width * 0.80,
margin: EdgeInsets.only(
top: 30.0,
bottom: 10.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text(
"Navigate and ShowDialog Button",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontFamily: "Quando"),
),
),
],
),
),
),
But when I press the okay button in the dialog, the okay button does not work and it gives a that error;
Unhandled Exception: Null check operator used on a null value
This worked fine on DartPad:
void _incrementCounter() {
Navigator.of(context).push(MaterialPageRoute(
builder: (c) => Scaffold(body: Text('new page'))
));
showDialog(context: context,
builder: (c) => AlertDialog(content: Text('the dialog in it'),)
);
}
Notice that .push() returns a Future immediately. The dialog you show after that is shown on top of page 2, since we don't await for it.
I put the Dialog in my second page BottomBarD() and I displayed it based on a conditional field every time the BottomBarD() loads.
Related
I currently learning Flutter and I'm very new to it. in my app I used responsive grid package and add Text in responsive container. i wanted to go to another page when tap on this text but my bad it gives me this error.
The named parameter 'onTap' isn't defined.
Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'onTap'.
i used following code:
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
child: ResponsiveGridRow(children: [
ResponsiveGridCol(
lg: 12,
child: Container(
height: 400,
alignment: Alignment.center,
color: Colors.orange,
child: Column(
children: [
Container(
margin: EdgeInsets.only(top: 150),
alignment: Alignment.center,
child: Text("Welcome To",
style: TextStyle(
fontSize: 40,
color: Colors.white)),
),
Container(
alignment: Alignment.center,
child: Text("our App",
style: TextStyle(
fontSize: 40,
color: Colors.white,
fontWeight: FontWeight.bold)),
),
],
),
),
),
ResponsiveGridCol(
xs: 4,
md: 2,
child: Container(
height: 18,
alignment: Alignment.centerLeft,
child: Text("Login",
style: TextStyle(
fontSize: 13,
// decoration: TextDecoration.underline,
color: Colors.orange[800])),
onTap: () { // i got error here
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SignIn()),
);
}
),
)
]),
),
),
);
}
}
Your widget does not have an onTap property you need to create as show below by wrapping the widget that you need to be clickable with a gesture detector or InkWell
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SignIn()),
);
}
child:Container(
height: 18,
alignment: Alignment.centerLeft,
child: Text("Login",
style: TextStyle(
fontSize: 13,
// decoration: TextDecoration.underline,
color: Colors.orange[800])),
)),
The Container widget does not have onTap property try to wrap it in InkWell like this:
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SignIn()),
);
},
child: Container(
height: 18,
alignment: Alignment.centerLeft,
child: Text("Login",
style: TextStyle(
fontSize: 13,
// decoration: TextDecoration.underline,
color: Colors.orange[800])),
)))
Flutter & AlertDialog : My app doesn't show the alert dialog after loading.
Even the 2 prints before and after the alert dialog was printed, the dialog was skip. Why is that? Please help me with this.
onTap: () async {
if (_formKey.currentState.validate() &&
_ratingStar > 0) {
setState(() {
_loading = true;
});
dynamic result =
await User_DatabaseService().uploadFeedback(
comment: review );
setState(() {
_loading = false;
});
if (result) {
print('Before dialog');
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0))),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(
vertical: 60, horizontal: 10),
child: Text(
//'Please rate with star',
'평가해 주셔서 감사합니다!',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
alignment: Alignment.center,
height: 50,
//color: primaryColor,
child: Text(
AppLocalizations.of(context)
.translate('OKAY'),
style: TextStyle(
color: Colors.white,
fontWeight:
FontWeight.bold),
),
),
),
],
),
);
},
);
print('After dialog');
Navigator.pop(context);
} else {
print('Sth wrong');
}
} else {
print('Not submit');
}
},
Please have a look on my code and tell me what's wrong. Thank you. I am looking forward to hearing from you.
Here is the problem:
if (result) {
print('Before dialog');
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0))),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(
vertical: 60, horizontal: 10),
child: Text(
//'Please rate with star',
'평가해 주셔서 감사합니다!',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
alignment: Alignment.center,
height: 50,
//color: primaryColor,
child: Text(
AppLocalizations.of(context)
.translate('OKAY'),
style: TextStyle(
color: Colors.white,
fontWeight:
FontWeight.bold),
),
),
),
],
),
);
},
);
print('After dialog');
Navigator.pop(context);
} else {
print('Sth wrong');
}
You are presenting the dialogue, then popping it. Make sure to add the Navigator.pop(context) method, only after you click a button on the alert dialogue. So, rewrite the code like this:
if (result) {
print('Before dialog');
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0))),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(
vertical: 60, horizontal: 10),
child: Text(
//'Please rate with star',
'평가해 주셔서 감사합니다!',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
alignment: Alignment.center,
height: 50,
//color: primaryColor,
child: Text(
AppLocalizations.of(context)
.translate('OKAY'),
style: TextStyle(
color: Colors.white,
fontWeight:
FontWeight.bold),
),
),
),
],
),
);
},
);
print('After dialog');
} else {
print('Sth wrong');
}
The issue lies in the line just after the print('After dialog') line. You are doing a Navigator.pop(context); which is basically removing the dialog from the navigation stack.
In flutter:
The showDialog() is used to show the dialog. And the Navigator.pop(context) is used to remove the dialog
I want to create a custom dialog as shown below. I am able to create a normal dialog with two buttons(the positive and negative buttons). But I searched a lot about creating custom dialog like the one shown below but in vain.
showAlertDialog(BuildContext context) {
// set up the buttons
Widget cancelButton = FlatButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget continueButton = FlatButton(
child: Text("Continue"),
onPressed: () {},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("Action"),
content: Text("Would you like to continue learning how to use Flutter alerts?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Now I want to have these buttons and the image as the children of the dialog and the icon button 'X' in the bottom to close the dialog. Any help is appreciated. I am a complete beginner in flutter.
For it, we create a custom dialog
1. Custom Dialog Content class
class CustomDialog extends StatelessWidget {
dialogContent(BuildContext context) {
return Container(
decoration: new BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10.0,
offset: const Offset(0.0, 10.0),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min, // To make the card compact
children: <Widget>[
Image.asset('assets/images/image.jpg', height: 100),
Text(
"Text 1",
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w700,
),
),
SizedBox(height: 16.0),
Text(
"Text 1",
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w700,
),
),
SizedBox(height: 24.0),
Align(
alignment: Alignment.bottomCenter,
child: Icon(Icons.cancel),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0.0,
backgroundColor: Colors.transparent,
child: dialogContent(context),
);
}
}
2. Call Custom Dialog on Click:
RaisedButton(
color: Colors.redAccent,
textColor: Colors.white,
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return CustomDialog();
});
;
},
child: Text("PressMe"),
),
I am using an Alert Dialog for the popups in my app. When the onTap is triggered the popup gets called however when I press the 'Cancel' button the popup does not dismiss and the whole screen behind the popup goes black.
This is my code for the popup.
import 'package:flutter/material.dart';
class FancyAlertDialog {
static showFancyAlertDialog(
BuildContext context,
String title,
String message,
{
bool dismissable = true,
Icon icon,
#required String labelPositiveButton,
#required String labelNegativeButton,
#required VoidCallback onTapPositiveButton,
#required VoidCallback onTapNegativeButton,
}) {
assert(context != null, 'context is null!!!');
assert(title != null, 'title is null!!!');
assert(message != null, 'message is null!!!');
assert(labelPositiveButton != null, 'labelPositiveButton is null');
assert(labelNegativeButton != null, 'labelNegativeButton is null');
assert(onTapPositiveButton != null, 'onTapPositiveButton is null');
assert(onTapNegativeButton != null, 'onTapNegativeButton is null');
return showDialog(
context: context,
barrierDismissible: dismissable,
child: Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(4.0),
),
),
child: Wrap(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(4.0),
topRight: Radius.circular(4.0),
),
color:Colors.red,
),
padding: EdgeInsets.symmetric(vertical: 5.0),
child: Stack(
children: <Widget>[
Align(
child: icon ?? Container(height:0),
alignment: Alignment.topRight,
)
],
),
),
Padding(
padding: EdgeInsets.only(
left: 16.0,
top: 2.0,
right: 16.0,
bottom: 8.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Center(
child: Text(
title,
style: Theme.of(context).textTheme.subtitle,
),
),
SizedBox(height: 8.0),
Text(
message,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.caption,
),
SizedBox(height: 16.0),
Row(
children: <Widget>[
Expanded(
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(16.0),
),
),
color: Colors.grey,
child: Text(
labelNegativeButton.toUpperCase(),
style: TextStyle(
color: Colors.white,
),
),
onPressed: onTapNegativeButton,
),
),
SizedBox(width: 16.0),
Expanded(
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(16.0),
),
),
color: Colors.red,
child: Text(
labelPositiveButton.toUpperCase(),
style: TextStyle(
color: Colors.white,
),
),
onPressed: onTapPositiveButton,
),
),
],
)
],
),
),
],
),
),
);
}
}
And this is how I've called the popup.
FancyAlertDialog.showFancyAlertDialog(
context,
'Info Fancy Alert Dialog Box',
'This is a info alert dialog box. This plugin is used to help you easily create fancy dialog',
icon: Icon(
Icons.clear,
color: Colors.black,
),
labelPositiveButton: 'OKAY',
onTapPositiveButton: () {
Navigator.pop(context);
print('tap positive button');
},
labelNegativeButton: 'Cancel',
onTapNegativeButton: () {
Navigator.pop(context);
print('tap negative button');
},
);
This is what my screen looks like when I press the cancel button:
Try this inside your onTap():
Navigator.of(context, rootNavigator: true).pop();
I assume you are using the wrong context object when calling Navigator.pop(context).
At that point the Navigator isn't aware of the dialog yet.
First, provide a new BuildContext within showDialog. There are two ways to do that:
Create a new widget for the child parameter (now Dialog) in the showDialog function.
Wrap the child (Dialog) with a Builder that provides a new BuildContext
Then you should get that new context to the Navigator.pop(context) call. Again, there are two ways to do that:
Pop from within the dialog itself
Pass the context object along as a parameter to the onTapPositiveButton and onTapNegativeButton
More info on the Builder can be found here as well: https://www.youtube.com/watch?v=xXNOkIuSYuA
Try to use this
onTap: () => Navigator.of(context).pop(false),
This is my dialog Code
Here is am getting an error of setstate() or MarkerneedsBuild called during the build. this overlay widget cannot be marked as needing to process of building widgets.
When I am trying to call _onAlertOtp widget it will show me this error.in the build method, i've bloc and state when my signup is successful then i have to call alert dialog. but when I am trying to do that it will show me the error. Hope you understand the question please help me.
_onAlertotp(BuildContext context) {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Enter OTP'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 2.7,
width: MediaQuery.of(context).size.width,
alignment: Alignment.center,
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
'We have Texted and/or Emailed OTP (One Time Pin) to your registered cell phone and/ or email account. Please check and enter OTP below to activate your TUDO account.',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 15),
textAlign: TextAlign.center,
),
),
SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 30),
child: PinCodeTextField(
length: 6, // must be greater than 0
obsecureText: false, //optional, default is false
shape: PinCodeFieldShape
.underline, //optional, default is underline
onDone: (String value) {
setState(() {
passcode = value;
print(value);
});
},
textStyle: TextStyle(
fontWeight: FontWeight
.bold), //optinal, default is TextStyle(fontSize: 18, color: Colors.black, fontWeight: FontWeight.bold)
onErrorCheck: (bool value) {
setState(() {
hasError = value;
});
},
shouldTriggerFucntions:
changeNotifier.stream.asBroadcastStream(),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Text(
hasError
? "*Please fill up all the cells and press VERIFY again"
: "",
style: TextStyle(
color: Colors.red.shade300, fontSize: 12),
),
),
SizedBox(
height: 20,
),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: "Didn't receive the code? ",
style:
TextStyle(color: Colors.black54, fontSize: 15),
children: [
TextSpan(
text: " RESEND",
// recognizer: onTapRecognizer,
style: TextStyle(
color: colorStyles["primary"],
fontWeight: FontWeight.bold,
fontSize: 16))
]),
),
SizedBox(
height: 7,
),
Container(
margin: const EdgeInsets.symmetric(
vertical: 16.0, horizontal: 30),
child: ButtonTheme(
height: 50,
child: FlatButton(
onPressed: () async {
/// check the [_onData] fucntion to understand better
changeNotifier.add(Functions.submit);
// at first we will check error on the press of the button.
if (!hasError) {
_onAlertrunnigbusiness(context);
}
},
child: Center(
child: Text(
"VERIFY".toUpperCase(),
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold),
)),
),
),
decoration: BoxDecoration(
color: colorStyles["primary"],
borderRadius: BorderRadius.circular(5),
),
),
],
),
),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Regret'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Here Is Another DIalog. which open on first dialog verify button click
_onAlertrunnigbusiness(context) {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Are you running Business?'),
content: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 10,
),
Text(
"TUDO.App aims at Businesses bridging gaps between Business Service Providers and Consumers collaborate on unique technology platform. If you own a business, we strongly recommend, provide your business information to grow your customer base and expand your business services. Any questions? Call us #1-800-888-TUDO"),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FlatButton.icon(
icon: Icon(FontAwesomeIcons.arrowCircleRight),
label: Text('No'),
color: colorStyles["primary"],
textColor: Colors.white,
padding:
EdgeInsets.symmetric(vertical: 10, horizontal: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () {
NavigationHelper.navigatetoMainscreen(context);
},
),
SizedBox(height: 10),
FlatButton.icon(
icon: Icon(FontAwesomeIcons.arrowCircleRight),
label: Text('Yes'),
color: colorStyles["primary"],
textColor: Colors.white,
padding:
EdgeInsets.symmetric(vertical: 10, horizontal: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () {
NavigationHelper.navigatetoBspsignupcreen(context);
},
),
],
)
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
And Here i am calling my dialog
#override
Widget build(BuildContext context) {
return BlocListener<SignupBloc, SignupState>(
bloc: widget._signupBloc,
listener: (
BuildContext context,
SignupState currentState,
) {
if (currentState is InSignupState) {
_countries = currentState.countries.countries;
return Container(child: content(_signupBloc, context, _countries));
}
if (currentState is SignupButtonClickedEvent) {
print('SignupButtonClickedEvent clicked');
return Container();
}
if (currentState is SignupSuccessState) {
print(
' You are awesome. you have successfully registered without confirmation');
print(currentState.signupUser.toJson());
print("Hey Otp Is opned");
if (!_isError) {
return _onAlertotp(context);
}
// NavigationHelper.navigatetoMainscreen(context);
_isLoading = false;
showAlertBox = true;
return Container(
child: content(_signupBloc, context, _countries),
);
}
if (currentState is SignupVerficationOtp) {
print('signup verficitaion otp button clicked');
return Container();
}
return Container(child: content(_signupBloc, context, _countries));
},
);
}
}
try using below code to display an alert dialog
in place of return _onAlertotp(context);
WidgetsBinding.instance.addPostFrameCallback((_) {
// show alert dialog here
_onAlertotp(context);
});
You should use a BlocListener at the root of your build method to handle events that do not return a widget (in your case the showDialog method)
Your if (currentState is SignupSuccessState) { part would be in the BlocListener and not in the BlocBuilder