Flutter: Use appBar Widget in Floating Action Button instead of the appBar? - flutter

Here's the widget I'm using in the appBar;
appBar: AppBar(actions: <Widget>[myAppBarIcon()],)
And the code for the widget itself;
Widget myAppBarIcon() {
return ValueListenableBuilder(
builder: (BuildContext context, int newNotificationCounterValue,
Widget child) {
return newNotificationCounterValue == 0? Container(): Stack(
children: [
Icon(
Icons.notifications,
color: Colors.white,
size: 30,
),
Container(
width: 30,
height: 30,
child: Container(
width: 15,
height: 15,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xffc32c37),
border: Border.all(color: Colors.white, width: 1)),
child: Padding(
padding: const EdgeInsets.all(0.0),
child: Text(
newNotificationCounterValue.toString(),
),
),
),
),
],
);
},
valueListenable: notificationCounterValueNotifer,
);
}
But I would now like to use the widget in a floating action button instead of the appBar. So here's what I tried;
Scaffold(
body: FoldableSidebarBuilder(
drawerBackgroundColor: Colors.black45,
drawer: CustomDrawer(closeDrawer: (){
setState(() {
drawerStatus = FSBStatus.FSB_CLOSE;
});
},),
screenContents: mainStage(),
status: drawerStatus,
),
floatingActionButton: Stack(
children: <Widget>[
Positioned(
bottom:140,
left: 17,
child: FloatingActionButton(
mini: true,
heroTag: null,
backgroundColor: Colors.black12,
child: myAppBarIcon()
),
),
],
),
),
But although no error comes up, myAppBarIcon isn't appearing in the build. Where did I go wrong?

Turns out it does work. I didn't think so at first till I realized I needed to receive an FCM notification before it appeared. This line was the reason.;
return newNotificationCounterValue == 0? Container()
So I'm going to put an empty notification icon in the container.

Related

button shadow when clicked is covered by other widget

Button's shadow is happened when click the button.
But, the shadow is covered by other widget.
How can I resolve this?
#override
Widget build(BuildContext context) {
int total = 0;
for (int i = 1; i <= count; i++) {
total += i;
}
return Stack(
clipBehavior: Clip.none,
children: [
Container(
width: 343.43,
height: 150.62,
decoration: RadiusAndShadow().getDecoration(),
child: Column(
children: <Widget>[
Header(text: name),
EcRow(t1: '칼로리', t2: '1회당 ${calorie}kcal'),
EcRow(t1: '카드개수', t2: '$count 개'),
EcRow(t1: '반복횟수', t2: '$total회'),
],
),
),
Positioned(
width: 343.43,
height: 150.62,
top: 17,
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
),
child: IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ExEdit();
}));
},
icon: const Icon(
Icons.edit_outlined,
color: Colors.white,
size: 30,
),
),
),
),
),
],
);
}
I used Stack widget.
In Stack, there are Container and Positioned.
In Container, there are Header and Text.
In Positioned, there is an IconButton.
I didn't understand exactly what happens since you did not provide any code, but I think when you click on the IconButton a splash effect happens and not exactly a shadow so inside the IconButton add:
splashRadius: 20,
you can also disable this effect:
return Theme(
data: ThemeData.light().copyWith(
textTheme: GoogleFonts.poppinsTextTheme(),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: const WelcomeScreen(),
);
Wrap your IconButton with widget Material
in Material
color: Colors.transparent,
in IconButton
splashRadius: 20,

How to get an image above background while shadowing background in flutter

I have an image and I want it to appear on my screen, above my background, with keeping background a bit dark type like in the image. I am thinking on using AlertDialog to display the image, but if you think there is a better way of doing it or a specific widget for this, please do tell me. Also please tell me what do we name this kind of image which hovers over background and focusing itself in UI.
enter code here
Just for trying out, I used this in my screen's initstate, as I want it to appear as soon as my screen appears -
super.initState();
showDialog(
context: context,
builder: (BuildContext buildContext) {
return AlertDialog(
content: Center(
child: Container(
color: Colors.red,
width: 200,
height: 200,
),
),
);
}
);
initState doesn't contain context you can get context after first frame.
You can use addPostFrameCallback
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
showDialog(..);}
Or Future.delayed
Future.delayed(Duration.zero).then((value) {
showDialog(..); }
The dialog construction is :
showDialog(
context: context,
builder: (BuildContext buildContext) {
const double iconSize = 48;
return LayoutBuilder(
builder: (context, constraints) => AlertDialog(
backgroundColor: Colors.transparent,
elevation: 0,
contentPadding: EdgeInsets.zero,
content: SizedBox(
width: constraints.maxWidth * .75,
height: constraints.maxHeight * .75,
child: Stack(
children: [
///background image with fit Cover
Align(
alignment: Alignment.center,
child: Container(
width: constraints.maxWidth * .75 - iconSize,
height: constraints.maxHeight * .75 - iconSize,
color: Colors.cyanAccent,
),
),
Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Container(
decoration: const BoxDecoration(
color: Colors.white, shape: BoxShape.circle),
child: const Icon(
Icons.close,
size: iconSize,
),
),
),
)
],
),
),
),
);
},
);
You can use Stack widget withe three widget as children.
first children widget is your background screen.
second children widget is a Container widget with color .withOpacity().
third children widget is the image you are trying to show on top.
Like this:
return Scaffold(
body: Stack(
children: [
Container(
color: Colors.white,
),
Container(
color: Colors.black.withOpacity(0.5),
),
Center(
child: Container(
height: MediaQuery.of(context).size.height * 70 / 100,
width: MediaQuery.of(context).size.width * 80 / 100,
color: Colors.purple,
),
),
],
),
);
for Visibility issue you can use this.
bool isVisible = false;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Stack(
children: [
Container(
color: Colors.red,
child: Center(
child: Container(
child: TextButton(
onPressed: () {
setState(() {
isVisible = true;
});
},
child: Text('Show Widget'),
),
),
),
),
Visibility(
visible: isVisible,
child: GestureDetector(
onTap: () {
setState(() {
isVisible = false;
});
},
child: Container(
color: Colors.white.withOpacity(0.5),
),
),
),
Visibility(
visible: isVisible,
child: Center(
child: Container(
height: MediaQuery.of(context).size.height * 70 / 100,
width: MediaQuery.of(context).size.width * 80 / 100,
color: Colors.purple,
child: Stack(
children: [
Positioned(
top: 0.0,
right: 0.0,
child: IconButton(
icon: const Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
setState(() {
isVisible = false;
});
},
),
),
],
),
),
),
),
],
),
);
}

How do I get a black banner with text to dynamically show depending upon what a user does on another screen in Flutter?

I am tasked with the challenge of getting a black banner to show when a user returns from a screen on that same tab upon ordering an item on another screen. The current code below only shows the black banner appropriately if the user leaves by selecting another tab then returns to the screen. The part that I need to be dynamically presented starts with "if (OrderProvider.listOrderSummary.isNotEmpty)". I believe that this involves making a stateless widget stateful, but that results in errors that suggest that may not be the right approach.
class GridItems extends StatelessWidget {
GridItems({#required this.infinityPageController});
final InfinityPageController infinityPageController;
#override
Widget build(BuildContext context) {
final List<Item> itemList = Provider.of<List<Item>>(context);
if (itemList == null) {
return Center(
child: CupertinoActivityIndicator(
radius: 20,
),
);
}
final List<Item> mapItemList = itemList.toList();
return Column(
children: <Widget>[
TopMenuNavigation(
infinityPageController: infinityPageController,
title: 'ALL ITEMS',
),
Divider(
color: Colors.grey,
),
Expanded(
child: GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: itemList.length,
itemBuilder: (BuildContext contex, int index) {
return Center(
child: InkWell(
onTap: () {
Navigator.of(context)
.pushNamed('/order', arguments: mapItemList[index]);
},
child: Container(
width: 310,
margin: EdgeInsets.all(7),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1, color: Colors.grey),
borderRadius: BorderRadius.all(
Radius.circular(7.0),
),
),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10, top: 10),
width: double.infinity,
child: Text('${mapItemList[index].itemName}'),
),
Expanded(
child: Image.network(
'${mapItemList[index].imageUrl}',
),
),
],
),
),
),
);
},
),
),
if (OrderProvider.listOrderSummary.isNotEmpty)
GestureDetector(
onTap: () {
Navigator.of(context).pushNamed('/review_order');
},
child: Container(
height: 55,
color: Colors.black,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Spacer(),
Text(
'REVIEW ORDER (${OrderProvider.listOrderSummary.length} items)',
style: TextStyle(
fontSize: 17,
color: Colors.white,
fontFamily: 'OpenSans',
fontWeight: FontWeight.bold),
),
SizedBox(width: 8),
Icon(
Icons.navigate_next,
color: Colors.white,
size: 35,
),
SizedBox(
width: MediaQuery.of(context).size.height * 0.065,
),
],
),
),
)
else
SizedBox(),
],
);
}
}
You have to somehow rebuild your screen (or part of it) where you want to return to. This is where a state-management solution should come into place :).
Create a BLoC or a ValueNotifier and rebuild the widget with a StreamBuilder or a ValueListenableBuilder. If you want to make it simple just create a shared state inside a stateful widget between your tab screens and call setState if the black banner should appear

How to overlap two circles?

Can someone help me get this layout with the first circle over the second?
image
I have this function:
Widget overlapped() {
final overlap = 25;
final items = [
Container(
padding: EdgeInsets.only(right: 2),
decoration: new BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: CircleAvatar(
radius: 22,
backgroundImage: AssetImage('assets/example_logo.png'),
backgroundColor: Colors.black,
),
),
CircleAvatar(
radius: 22,
backgroundColor: Colors.white,
child: ClipOval(
child: Image.network(
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/1200px-Google_%22G%22_Logo.svg.png",
errorBuilder: (context, exception, stackTrace) {
return Container(color: Colors.white);
},
height: 35,
))),
CircleAvatar(
child: Text('+2', style: TextStyle(color: Colors.white)),
backgroundColor: Theme.of(context).canvasColor),
];
List<Widget> stackLayers = List<Widget>.generate(items.length, (index) {
return Container(
padding: EdgeInsets.fromLTRB(index.toDouble() * overlap, 0, 0, 0),
child: items[index],
);
});
return Stack(children: stackLayers);
}
This function whenever I add an item to the array, it adds a widget on the right. But I want the first to be above the second, the second of the third, etc ...
you could use the Stack widget :
Stack(
children:<Widget>:[
Positioned(
right: 130.0,
child:Container(
shape: BoxShape.circle,
)
),
Positioned(
left: 130.0,
child:Container(
shape: BoxShape.circle,
)
),
]
)
Use Stack and Positioned together.
import 'package:flutter/material.dart';
class OverLap extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Overlap'),
),
body: Container(
padding: const EdgeInsets.all(8.0),
width: 500.0,
child: Stack(
children: <Widget>[
//Change according to your icon
Icon(
Icons.flaky,
size: 50.0,
color: Colors.red,
),
Positioned(
left: 20.0,
//Change according to your icon
child: Icon(
Icons.flaky,
size: 50.0,
color: Colors.blue,
),
),
],
),
),
);
}
}

Flutter: How to change the width of an AlertDialog?

I wonder how to change the default width of an AlertDialog, I only succeeded to change the border radius :
Here is my code :
showDialog(
context: context,
builder: (_) =>
new AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))
),
content: ProductPreviewScreen(),
)
);
Result expected :
Any idea?
As of May 2020, if you want to change the inset padding of a dialog, all you have to do is use the Dialog class and override the 'insetPadding' property. You can make a dialog extend all the way to the screen edges if you want to.
You can also make some cool custom dialogs by making the dialog surface itself transparent and then add whatever widgets you want. For example:
showDialog(Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(10),
child: Stack(
overflow: Overflow.visible,
alignment: Alignment.center,
children: <Widget>[
Container(
width: double.infinity,
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.lightBlue
),
padding: EdgeInsets.fromLTRB(20, 50, 20, 20),
child: Text("You can make cool stuff!",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center
),
),
Positioned(
top: -100,
child: Image.network("https://i.imgur.com/2yaf2wb.png", width: 150, height: 150)
)
],
)
));
Results in:
This is much more simple then the other answers make it out to be. Just use a builder to change the size of the dialog as it is being built(constructed, instantiated in other languages). This means you can also query the screen size and make a decision on how much space you want depending on said screen size. For example more space on a tablet then on a phone. You can make Scaffold a child of the Container if you need the App bar and other functions.
showDialog(
context: context,
builder: (_) => new AlertDialog(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(10.0))),
content: Builder(
builder: (context) {
// Get available height and width of the build area of this widget. Make a choice depending on the size.
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
return Container(
height: height - 400,
width: width - 400,
);
},
),
)
);
Examples of different sizes:
Optionally add these to remove unneeded inner/outer border space.
insetPadding: EdgeInsets.zero,
contentPadding: EdgeInsets.zero,
clipBehavior: Clip.antiAliasWithSaveLayer,
Using built-in dialog:
To increase the width:
AlertDialog(
title: Text("AlertDialog"),
insetPadding: EdgeInsets.zero,
)
To decrease the width:
AlertDialog(
title: Text("AlertDialog"),
insetPadding: EdgeInsets.symmetric(horizontal: 100),
)
Using custom dialog:
Call this method:
showGeneralDialog(
context: context,
barrierColor: Colors.black.withOpacity(0.5),
pageBuilder: (_, __, ___) {
return Material(
color: Colors.transparent,
child: Center(
child: Container(
color: Colors.white, // Dialog background
width: 120, // Dialog width
height: 50, // Dialog height
child: SingleChildScrollView(
child: Column(
children: [
Text('I am a small Dialog'),
],
),
),
),
),
);
},
);
You could try to wrap your AlertDialog widget with ConstrainedBox widget as suggested in here and set your desired value for maxWidth parameter.
UPDATED
I just looked at the code of the parent of the AlertDialog widget which is the Dialog widget and found out that it wrapped its child with a ConstrainedBox widget with a minWidth of 280 pixels. This is the reason why we can't change the width of the AlertDialog widget.
Fortunately, there are two things that we can do. First option would be to alter the default minWidth of the Dialog Widget inside the dialog.dart file. Note that changing this would affect all of your flutter projects that uses the Dialog widget.
//inside dialog.dart
class Dialog extends StatelessWidget {
...
#override
Widget build(BuildContext context) {
final DialogTheme dialogTheme = DialogTheme.of(context);
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets + const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
duration: insetAnimationDuration,
curve: insetAnimationCurve,
child: MediaQuery.removeViewInsets(
removeLeft: true,
removeTop: true,
removeRight: true,
removeBottom: true,
context: context,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: 280.0), // You can set your desired value for minWidth here
child: Material(
elevation: 24.0,
...
You can then use the AlertDialog like this:
showDialog(
context: context,
builder: (_) => AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))
),
contentPadding: EdgeInsets.all(0.0),
content: ProductPreviewScreen(),
)
)
);
The other way would be to create our own customize dialog.
showDialog(
context: context,
builder: (_) => Center( // Aligns the container to center
child: Container( // A simplified version of dialog.
width: 100.0,
height: 56.0,
color: Colors.pink,
)
)
);
Use Padding widget
Padding(
padding: EdgeInsets.only(left: 50.0, right: 50.0),
child://AlertDialog or any other Dialog you can use
Dialog(
elevation: 0.0,
backgroundColor: Colors.transparent,
child: Container(
width: 10.0,
height: 50.0,
color: Colors.red,
)
))
My solution is to enclose the Dialog in a widget that defeats the extra padding added by the Dialog class by modifying the MediaQueryData.
import 'package:myapp/widgets/dialog_inset_defeat.dart';
...
showDialog(
context: context,
builder: (_) => DialogInsetDefeat(
context: context,
child: SimpleDialog(...),
)
);
... or use showDialogWithInsets() for custom values:
showDialogWithInsets(
context: context,
edgeInsets: EdgeInsets.symmetric(horizontal: 8),
builder: (_) => SimpleDialog(...),
)
);
File dialog_inset_defeat.dart
import 'package:flutter/material.dart';
/// A widget to defeat the hard coded insets of the [Dialog] class which
/// are [EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0)].
///
/// See also:
///
/// * [Dialog], for dialogs that have a message and some buttons.
/// * [showDialog], which actually displays the dialog and returns its result.
/// * <https://material.io/design/components/dialogs.html>
/// * <https://stackoverflow.com/questions/53913192/flutter-change-the-width-of-an-alertdialog>
class DialogInsetDefeat extends StatelessWidget {
final BuildContext context;
final Widget child;
final deInset = EdgeInsets.symmetric(horizontal: -40, vertical: -24);
final EdgeInsets edgeInsets;
DialogInsetDefeat({#required this.context, #required this.child, this.edgeInsets});
#override
Widget build(BuildContext context) {
var netEdgeInsets = deInset + (edgeInsets ?? EdgeInsets.zero);
return MediaQuery(
data: MediaQuery.of(context).copyWith(viewInsets: netEdgeInsets),
child: child,
);
}
}
/// Displays a Material dialog using the above DialogInsetDefeat class.
/// Meant to be a drop-in replacement for showDialog().
///
/// See also:
///
/// * [Dialog], on which [SimpleDialog] and [AlertDialog] are based.
/// * [showDialog], which allows for customization of the dialog popup.
/// * <https://material.io/design/components/dialogs.html>
Future<T> showDialogWithInsets<T>({
#required BuildContext context,
bool barrierDismissible = true,
#required WidgetBuilder builder,
EdgeInsets edgeInsets,
}) {
return showDialog(
context: context,
builder: (_) => DialogInsetDefeat(
context: context,
edgeInsets: edgeInsets,
child: Builder(builder: builder),
),
// Edited! barrierDismissible: barrierDismissible = true,
barrierDismissible: barrierDismissible,
);
}
Works for me as of Flutter 1.8.3. YMMV
use Dialog()
Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
insetPadding: EdgeInsets.all(15),
child: SingleChildScrollView(
child: Container(),
),
),
);
Medling with insetWidth and future builder etc. didn't work for me - just editing the content prop's width worked perfectly.
showDialog(
context: context,
builder: (context) {
Future.delayed(Duration(seconds: 1000), () {
Navigator.of(context).pop(true);
});
return AlertDialog(
insetPadding: EdgeInsets.all(8.0),
title: Text(
"Time to go pro!",
textAlign: TextAlign.center,
),
content: Container(
width: MediaQuery.of(context).size.width,
child: BuySheet(
applePayEnabled: applePayEnabled,
googlePayEnabled: googlePayEnabled,
applePayMerchantId: applePayMerchantId,
squareLocationId: squareLocationId),
),
);
});
I finally found a way to change the width of an AlertDialog.
Just wrap the "content" with a Container, and set the width to it.
return AlertDialog(
...
content: Container(
width: MediaQuery.of(context).size.width*0.45,
child: ...
AlertDialog with width modified
You can change the AlertDialog property insetPadding it will be a simple way for you.
void alertBox() {
showDialog(
context: context,
builder: (context) => AlertDialog(
insetPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
// (horizontal:10 = left:10, right:10)(vertical:10 = top:10, bottom:10)
contentPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
content: Container(
width: MediaQuery.of(context).size.width - 20,
// width = device width minus insetPadding = deviceWidth - 20 (left:10, right:10 = 20)
height: MediaQuery.of(context).size.height - 20,
// height = device height minus insetPadding = deviceHeight - 20 (top:10, bottom:10 = 20)
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Card(
margin: EdgeInsets.zero,
color: Colors.amber,
),
),
),
),
);
}
Refer this code. you can change width and height of dialogue box by setting insetPadding, because it taking default padding so we need to change like this.
showDialog(
context: context,
builder: (_) =>
Dialog(
insetPadding: EdgeInsets.symmetric(horizontal: 2.0, vertical: 2.0),
backgroundColor: Colors.transparent,
child: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height*0.7 ,
decoration: BoxDecoration(
color: Colors.grey[900],
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
onTap: (){
Navigator.pop(context);
},
child: Icon(Icons.close,color: Colors.grey,)),
],
),
),
Text("select your avatar",style: TextStyle(color: white,fontWeight: FontWeight.bold),),
],
),
),
),
);
:
return Dialog(
backgroundColor: Colors.white,
insetPadding: EdgeInsets.all(10.0),
child: Container(
width: double.infinity,
use insetpadding where you are returning Dialog and give it a double value, For my case, i gave it a 10.0
insetPadding: EdgeInsets.all(10.0), you can give it a custom height
Hello you can actually use insetPadding and use a column inside content that will contain a SizedBox(width:MediaQuery.of(context).size.width).The only difference is that I used AlertDialog. Bellow is the way it worked for me. You can set dialog width by changing padding inside insetPadding. Hope i helped :).
dialog(){
TextEditingController controller = TextEditingController();
return showDialog(
context: context,
barrierDismissible: true,
builder: (_) => AlertDialog(
insetPadding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.08),
content: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 16,
width: MediaQuery.of(context).size.width,
),
Text(
'Hello',
),
SizedBox(
height: 15,
),
Text(
'Description',
),
TextField(
controller: controller,
style: TextStyle(
color: Colors.black,
),
),
],
),
),
actions: [
FlatButton(
child: Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
);
}
This is how it looks like
https://i.stack.imgur.com/bvKpP.png
Add InsetPadding property like this
insetPadding: EdgeInsets.zero
AlertDialog(
title: Center(child: Text("$title")),
------------------------->Here we added the property
insetPadding: EdgeInsets.zero,
titlePadding: EdgeInsets.only(top: 14.0, bottom: 4),
content: Container(
height: 50,
child: TextFormField(
controller: find_controller,
decoration: InputDecoration(
suffixIcon: context.watch<MediaProvider>().isChangeDialog
? IconButton(
onPressed: () {
clearController(find_controller);
},
icon: Icon(Icons.clear))
: null,
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.deepPurpleAccent)),
hintText: 'Id',
),
onChanged: (val) {
if (val.isNotEmpty)
context.read<MediaProvider>().isChangeDialog = true;
else
context.read<MediaProvider>().isChangeDialog = false;
},
),
),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: OutlinedButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Align(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Icon(Icons.clear),
),
),
Text("Cancel")
],
),
onPressed: () {
context.read<MediaProvider>().isChangeDialog = false;
Navigator.of(context).pop();
}),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: ElevatedButton(
onPressed: context.watch<MediaProvider>().isChangeDialog
? () {
context.read<MediaProvider>().isChangeDialog = false;
okCallback;
}
: null,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Align(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Icon(Icons.check),
),
),
Text("OK")
],
)),
)
],
),
],
);
Before
After
The solution that worked for me.
Set the insetPadding of the AlertDialog.
Plus, wrap the content in a SizedBox and set the width to MediaQuery.of(context).size.width.
return AlertDialog(
content: SizedBox(
width: MediaQuery.of(context).size.width,
child: const Text("Content"),
),
insetPadding: const EdgeInsets.all(10),
);
Setting just the insetPadding alone does not work.
return Dialog(
insetPadding: EdgeInsets.symmetric(
horizontal: X,
),
);
I found the simplest way... just add insetPadding: EdgeInsets.zero, and it will expand to max size width:
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Center(child: Text("Send Message", style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),)),
backgroundColor: Colors.indigo[700],
insetPadding: EdgeInsets.zero,
content:
As a workaround, you can play with the dialog title, in most cases the dialog will expand horizontally to accommodate the title. So you can create big title to make sure the dialog will take max width. Obviously you can't just put long title, but you can build your title of two text widgets, where one of them has text color matching background. For the case where no title should be shown:
showDialog(
context: context,
builder: (_) =>
new AlertDialog(
title: Text('hidden title, just set font text to the same as background.',
style: TextStyle(color: Colors.white)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))
),
content: ProductPreviewScreen(),
)
);
I am using get package and it is wonderful. use its dialog, easily sizable
Get.generalDialog(pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation,) {
return SimpleDialog(
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(Constants.padding), ),
elevation: 0, backgroundColor: Colors.transparent,
children: [Center(child: Stack(
children: <Widget>[
Container(width: Get.width * 0.95,
padding: const EdgeInsets.only(left: Constants.padding,top: Constants.avatarRadius
+ Constants.padding, right: Constants.padding,bottom: Constants.padding
),
margin: const EdgeInsets.only(top: Constants.avatarRadius),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Get.theme.scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(Constants.padding),
boxShadow: const [
BoxShadow(color: Colors.black,offset: Offset(0,10), blurRadius: 10 ),
]
),
child: Text('body'),
),
Positioned(
left: Constants.padding, right: Constants.padding,
child: CircleAvatar(
backgroundColor: Colors.blueAccent, radius: Constants.avatarRadius,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(Constants.avatarRadius)),
child: Icon(Icons.done, size: 24, color: Colors.white,)
),
),
),
Positioned(
left: 0,
//right: Constants.padding,
child: CircleAvatar(
backgroundColor: Colors.blueAccent, radius: Constants.avatarRadius,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(Constants.avatarRadius)),
child: InkWell(child: const Icon(Icons.close, size: 24, color: Colors.white,), onTap: (){Get.back();},)
),
),
),
],
))],
);
}, barrierDismissible: true, barrierLabel: '');
Use width: MediaQuery.of(context).size.width to increase width of the alert
Example:
return AlertDialog(
title: Text("Select Birth Date"),
content: Container(
width: MediaQuery.of(context).size.width,
height: 300,
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: DateTime(1969, 1, 1),
onDateTimeChanged: (DateTime newDateTime) {
// Do something
},
),
),
actions: <Widget>[
FlatButton(
child: Text("Select"),
onPressed: () {
widget.onSelected(selectedDate);
Navigator.pop(context);
//.....
},
),
],
);
/// this works for me paste your body and see result
Future _showDialog() async {
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Material(
color: Colors.transparent,
child: Container(
padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.all(10),
/// paste your item body
child:body,
),
),
],
),
);
},
);
}
In my case, I was using listview inside the dialog box so I was not using
shrink wrap inside ListView hopes this will help someone.
ListView.builder(
shrinkWrap : true...
...
};