Reputation: 1316
I have a popup as given below. I'm trying to position a close button in the top right corner of the popup but there seems to be some extra space there that I can't get rid of.
I am also facing an error where when I press the OKAY button the popup doesn't get dismissed even though I am supplying it with a Navigator.pop(context).
This is my code:
class Popup {
final String title;
final String message;
final String rightButton;
final VoidCallback onTapRightButton;
final String leftButton;
final VoidCallback onTapLeftButton;
...
show(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return _PopupCall(
title: title,
message: message,
leftButton: leftButton ?? 'null',
rightButton: rightButton,
onTapLeftButton: onTapLeftButton,
onTapRightButton: onTapRightButton);
},
);
}
...
@override
Widget build(BuildContext context) {
return ScaleTransition(
scale: scaleAnimation,
child: AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(24),
),
),
title: Wrap(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: IconButton(
icon: Icon(
Icons.close,
color: Colors.red,
size: 25,
),
onPressed: () {
Navigator.pop(context);
},
),
),
Center(
child: Text(widget.title,
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.bold,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 25,
color: Colors.yellow,
)),
),
const SizedBox(height: 15.0),
Text(widget.message,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.w400,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 15,
color: Colors.yellow,
)),
const SizedBox(height: 16.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Visibility(
visible: widget.leftButton != 'null',
child: Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: Center(
child: GestureDetector(
onTap: () {
if (widget.leftButton != 'null') {
widget
.onTapLeftButton(); //function to be performed onTap
}
Navigator.pop(context);
},
child: Container(
height: 40,
width: 80,
decoration: BoxDecoration(
border: Border.all(
color: Colors.yellow, width: 2.0),
borderRadius: BorderRadius.all(
Radius.circular(25),
),
color: Colors.blue),
child: Center(
child: Text('Okay',
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.bold,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 15,
color: Colors.yellow,
)),
),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(
bottom: 10.0,
left: 10,
),
child: Center(
child: GestureDetector(
onTap: () {
widget
.onTapRightButton(); //function to be performed onTap
Navigator.pop(context);
},
child: Container(
height: 40,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(15),
),
gradient: kGradientBackground,
),
child: Center(
child: Text(widget.rightButton.toUpperCase(),
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.bold,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 15,
color: Colors.blue,
)),
),
),
),
),
),
],
),
],
),
],
),
),
);
}
This is what the popup looks like:
This is how I'm calling my popup:
Popup(
title: 'Oops!',
message:
"Looks like there has been a mistake please check later!",
rightButton: 'OK',
onTapLeftButton: () {},
onTapRightButton: () {},
).show(context);
Upvotes: 2
Views: 10444
Reputation: 8383
If you look at the Flutter Inspector , you will understand the structure of your Popup Dialog:
The position of the close icon is defined by the AlertDialog
's titlePadding
in dark blue and the IconButton
padding in lighter blue. If you set the titlePadding
to zero, you might have the position you want for the close Icon:
However, now, the content of your AlertDialog is too close to the border of the dialog's frame. I suggest moving the content of the Dialog to the content
field instead of having everything inside the title
:
You could go one step further by moving the action buttons to the actions
field of your AlertDialog
.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
),
);
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => Popup(
title: 'Oops!',
message: "Looks like there has been a mistake please check later!",
leftButton: 'Cancel',
rightButton: 'OK',
onTapLeftButton: () {},
onTapRightButton: () {},
).show(context),
child: Text('SHOW POPUP'),
),
),
);
}
}
class Popup {
final String title;
final String message;
final String rightButton;
final VoidCallback onTapRightButton;
final String leftButton;
final VoidCallback onTapLeftButton;
Popup({
this.title,
this.message,
this.rightButton,
this.onTapRightButton,
this.leftButton,
this.onTapLeftButton,
});
show(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return _PopupCall(
title: title,
message: message,
leftButton: leftButton,
rightButton: rightButton,
onTapLeftButton: onTapLeftButton,
onTapRightButton: onTapRightButton);
},
);
}
}
class _PopupCall extends StatefulWidget {
final String title;
final String message;
final String rightButton;
final VoidCallback onTapRightButton;
final String leftButton;
final VoidCallback onTapLeftButton;
const _PopupCall(
{Key key,
this.title,
this.message,
this.rightButton,
this.onTapRightButton,
this.leftButton,
this.onTapLeftButton})
: super(key: key);
@override
_PopupCallState createState() => _PopupCallState();
}
class _PopupCallState extends State<_PopupCall> {
@override
Widget build(BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(24),
),
),
backgroundColor: Colors.black87,
titlePadding: EdgeInsets.all(0),
title: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: IconButton(
icon: Icon(
Icons.close,
color: Colors.red,
size: 25,
),
onPressed: () {
Navigator.pop(context);
},
),
),
Center(
child: Text(widget.title,
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.bold,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 25,
color: Colors.yellow,
)),
),
],
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
widget.message,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.w400,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 15,
color: Colors.yellow,
),
),
],
),
actions: [
if (widget.leftButton != null)
Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: Center(
child: GestureDetector(
onTap: () {
widget.onTapLeftButton?.call();
Navigator.pop(context);
},
child: Container(
height: 40,
width: 80,
decoration: BoxDecoration(
border: Border.all(color: Colors.yellow, width: 2.0),
borderRadius: BorderRadius.all(
Radius.circular(25),
),
color: Colors.blue,
),
child: Center(
child: Text(
'Okay',
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.bold,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 15,
color: Colors.yellow,
),
),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(
bottom: 10.0,
left: 10,
),
child: Center(
child: GestureDetector(
onTap: () {
widget.onTapRightButton?.call();
Navigator.pop(context);
},
child: Container(
height: 40,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(15),
),
),
child: Center(
child: Text(
widget.rightButton.toUpperCase(),
style: TextStyle(
fontFamily: 'TTNorms',
fontWeight: FontWeight.bold,
wordSpacing: 0,
letterSpacing: 0,
fontSize: 15,
color: Colors.blue,
),
),
),
),
),
),
)
],
);
}
}
Upvotes: 2
Reputation: 931
Modify your class to retrieve a function from Stateful Widget. Pass your Navigator.pop(context)
action to that function when showing your popup. Inside the popup class, use that passed function to dismiss itself.
Upvotes: 0