How to use Image inside Stack widget in Flutter? - flutter

I got an error when using Image inside Stack widget :
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
...
this is my code :
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(25.0),
child: Flexible(
child: Image.asset(itemData["image"])
),
),
const Positioned(
...
),
],
),
],
),
);
}
of course, I defined my image assets in pubspec.yaml and I try to remove flexible widget also add Row layer above it, but it's still not working either...
this is my error when I remove flexible widget :
The following assertion was thrown resolving an image codec:
Unable to load asset: assets/images/image2.jpg
When the exception was thrown, this was the stack:
#0 PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:237:7)
<asynchronous suspension>
#1 AssetBundleImageProvider._loadAsync (package:flutter/src/painting/image_provider.dart:675:14)
<asynchronous suspension>
Image provider: AssetImage(bundle: null, name: "assets/images/image2.jpg")
Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#898db(), name:
"assets/images/image2.jpg", scale: 1.0)
So, How I can use (multiple) Images inside Stack Widget, and what's wrong with my code?
thank you for coming and I hope you have the solution. cheers

You have done everything perfect. but the one mistake was you wraped Image Widget by flexible. thats why flutter throws error. below code will work fine.
just remove flexible widget.
Container(
margin: const EdgeInsets.symmetric(vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(25.0),
child: Image.network(
"https://www.writerswrite.co.za/wp-content/uploads/2017/04/how-long-to-read.png",
),
),
Positioned(
child: Container(
height: 20,
color: Colors.red,
width: 20,
),
),
],
),
],
),
);
Flexible Widget used to adjust the available space near the widgets...
so renderobject not able to paint what you construct in UI because of you wraped flexible over Image
to learn more about flexible refer : https://api.flutter.dev/flutter/widgets/Flexible-class.html
above code will working fine...
for image rendering issue : refer https://docs.flutter.dev/development/platform-integration/web-images

Wrap the Stack with expanded widget. I tried with the example below and it worked for me
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(25.0),
child: Flexible(
child: Image.network(
"https://www.writerswrite.co.za/wp-content/uploads/2017/04/how-long-to-read.png",
),
),
),
Positioned(
child: Container(
height: 20,
color: Colors.red,
width: 20,
),
),
],
),
),
],
),
);
}

Related

How to fix Flutter web release showing grey screen but no debug error

I have created a flutter webapp but I have a screen that shows a grey page not sure why, I think its something to do with the listview since all pages with the listview have the same problem. Can you take a look at the code below to figure out the problem?
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
endDrawer: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 300),
child: const SideMenu()),
body: SingleChildScrollView(
child: SafeArea(
child: Container(
width: size.width,
constraints: BoxConstraints(minHeight: size.height),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const NavBar(),
This is where the grey screen start to appears
const BrowseScreenBody(),
const Footer(),
]),
),
),
),
);
}
}
class BrowseScreenBody extends StatelessWidget {
const BrowseScreenBody({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final events = Event.events.toList();
return Container(
margin: const EdgeInsets.symmetric(vertical: 20, horizontal: 40),
child: Expanded(
child: Padding(
padding: ...,
child: Column(
children: <Widget>[
RichText(
text: TextSpan(
children: [
...
],
),
),
//Events Lists
SizedBox(
height: size.height * 0.65,width: size.width,
child: ListView.builder(
shrinkWrap: true,
itemCount: events.length,
itemBuilder: (context, index) {
final event = events[index];
return Card(
child: Container(
decoration: BoxDecoration(
color: Colors.white),
child: Padding(
padding: ...
child: Column(
children: [
Row(
children: [
Container(
height: size.height * 0.25,
width: size. Width * 0.4,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(...))),
),
Row(
children: [
Column(
children: [...
],
),
],
)
],
)
],
),
),
),
);
}),
),
],
),
),
));
}
}
Everything works well on debug mode, but when hosted to github pages I can't seem to get the widgets shown.
The problem is that you are using an Expanded as child of a Container. Expanded can only be a child of a Flex widget like Row or Column. But it's very likely that you actually do get errors in debug mode as well in your console. Because when I tried your code (slightly modified to make it runnable) it did give an error. Something like
======== Exception caught by widgets library =======================================================
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type BoxParentData.
Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a Padding widget.

Flutter: Combining ScrollView and PageView Widgets

body: SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(height: 600, color: Colors.red),
Container( // <------ Container A
child: PageView(
controller: _activityPanelController,
children: [
Container(height: 300, color: Colors.white),
Container(height: 300, color: Colors.blue),
],
),
),
],
),
),
),
I want to set the Container A's height to its child to use the PageView widget inside the SingleChildScrollView in this case.
How can I achieve to put the PageView widget inside the SingleChildScrollView widget?
Unfortunately, you can't make PageView as high as it's children. You'd do so with IntrinsicHeight widget and by removing SizedBox, but you'll get the following error:
The following assertion was thrown during performLayout():
RenderViewport does not support returning intrinsic dimensions.
Also, you can't get rid of the SizedBox, because of the ListView (the same happens with Column and SingleChildScrollView), it's children get unbounded height, and PageView tries to get as big as possible. After removing SizedBox, you'll see this:
The following assertion was thrown during performResize():
Horizontal viewport was given unbounded height.
Working example:
#override
Widget build(BuildContext context) {
final boxHeight = 600.0;
return ListView(
children: <Widget>[
Container(height: boxHeight, color: Colors.red),
Container(height: boxHeight, color: Colors.deepPurpleAccent),
SizedBox(
height: boxHeight,
child: PageView(
controller: PageController(),
children: [
// ...
].map((e) => SingleChildScrollView(child: e)).toList(),
),
),
],
);
}
https://www.dartpad.dev/619458e188ce97f9cd1272441b7a3bf3?null_safety=true

How to make the Wrap widget child inside SingleChildScrollView to expand to full height in Flutter?

I'm trying to make a UI where there are some text fields inside a container and there are some icon buttons which are always going to stay at the bottom.
Here is the code minimal code
Center(
child: Container(
// width: 1006,
constraints: BoxConstraints(
maxWidth: 1006,
maxHeight: sizingInformation.screenSize.height,
),
margin: EdgeInsets.only(
left: isMobile ? 0 : 34,
),
child: Flex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Flex(
// rest of the widgets
),
Expanded(
child: Container(
padding: EdgeInsets.all(isMobile ? 15 : 34),
margin: EdgeInsets.only(
top: isMobile ? 15 : 27,
),
constraints: BoxConstraints(
maxWidth: 1006,
),
height: 750,
decoration: BoxDecoration(
color: CARD_DARK_PURPLE,
borderRadius: BorderRadius.circular(8),
),
child: SingleChildScrollView(
physics: AlwaysScrollableScrollPhysics(),
child: Wrap(
direction: Axis.horizontal,
children: <Widget>[
Wrap(
direction: Axis.horizontal,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Pošiljalac",
style: TextStyle(
color: WHITE,
fontSize: isMobileTablet ? 22 : 24,
fontWeight: BOLD,
),
),
SizedBox(
height: 20,
),
_phoneInfo(widget.order.senderPhoneNumber, isMobile),
_emailInfo(widget.order.senderEmail, isMobile),
_fullNameInfo(widget.order.senderFirstName,
widget.order.senderLastName, isMobile, isMobileTablet),
_addressInfo(widget.order.senderStreetNumber, isMobile),
_zipCodeInfo(widget.order.senderZipCode, isMobile),
_cityInfo(widget.order.senderCity, isMobile),
SizedBox(
height: isDesktopLaptop ? 14 : 0,
),
_payeeInfo(isMobile, isMobileTablet),
],
),
SizedBox(
width: 34,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: isDesktopLaptop ? 482 : 10,
),
_weightInfo(isMobile, isMobileTablet),
_noteSmall(isMobile, isMobileTablet),
],
),
],
),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(height: 10),
Flex(
direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(width: 20),
Material(
color: DIVIDER,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Center(
child: Ink(
decoration: const ShapeDecoration(
color: DIVIDER,
shape: CircleBorder(),
),
child: IconButton(
splashColor: DARK_PURPLE.withOpacity(0.3),
icon: Image.asset(
'assets/images/inter-note-icon.png',
width: 20,
height: 24,
),
onPressed: () {
if (widget.order.operatorNote == "/") {
_dialogs.internNoteDialog(
context,
widget.order.id,
"order",
widget.order.operatorNote);
} else {
_dialogs.changeInternNoteDialog(
context,
widget.order.id,
"order",
widget.order.operatorNote);
}
},
),
),
),
),
SizedBox(width: 20),
Material(
color: DIVIDER,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Center(
child: Ink(
decoration: const ShapeDecoration(
color: DIVIDER,
shape: CircleBorder(),
),
child: IconButton(
splashColor: DARK_PURPLE.withOpacity(0.3),
icon: Image.asset(
'assets/images/trash-icon.png',
width: 28,
height: 28,
),
onPressed: () {
_dialogs.deleteOrderDialog(
context, widget.order.id, isMobile);
},
),
),
),
),
],
),
],
),
),
],
),
),
),
),
),
),
)
This is the UI that I'm trying to achieve(the box highlighted on the right side specifically)
There is SingleChildScrollView parent which has Wrap as its child. SingleChildScrollView is taking the full height available but Wrap isn't spanning to that full height. I want to make the Wrap span full height so that the icons can stay at the bottom always.
So, I placed it inside Expanded as I thought it would make it expand to the full available height. But I got this error.
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type ParentData.
Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a _SingleChildViewport widget.
The ownership chain for the RenderObject that received the incompatible parent data was:
Wrap ← Expanded ← _SingleChildViewport ← IgnorePointer-[GlobalKey#01401] ← Semantics ← _PointerListener ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#7427b] ← _PointerListener ← ⋯
When the exception was thrown, this was the stack
dart:sdk_internal 4461:11 throw_
packages/flutter/src/widgets/widget_span.dart.lib.js 12339:23 <fn>
packages/flutter/src/widgets/widget_span.dart.lib.js 12355:24 [_updateParentData]
packages/flutter/src/widgets/widget_span.dart.lib.js 12372:61 attachRenderObject
packages/flutter/src/widgets/widget_span.dart.lib.js 12184:12 mount
...
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════
Incorrect use of ParentDataWidget.
════════════════════════════════════════════════════════════════════════════════
So, Expanded is not the answer to this. But I don't know what else is. I'm new to Flutter and having a hard time understanding the Flutter layout system. Any help would be great. Thanks for your time.
What if you make your Wrap widget the child of a container the size of the screen ?
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Wrap(
children: [],
))),
);
}
}

Stack widget not working as a child of Column widget

I am unable to successfully make Stack widget to work when i place it as a child of Column widget. My intention is to mix the Stack layout and Column/Row layout methods to reap the benefits of both approach. When i run the code the compile gave a scanty error message:
════════ (2) Exception caught by rendering library
═════════════════════════════════════════════════ A RenderFlex
overflowed by Infinity pixels on the bottom. User-created ancestor of
the error-causing widget was: Scaffold
file:///C:/Users/admin/AndroidStudioProjects/music_app/lib/main.dart:240:12
Blank white page was returned when i ran the code. What am i doing wrong? The following is the code snippet:
body: Column(
children: <Widget>[
Container(
child: Stack(
children: <Widget>[
Positioned(
top: 100,
left: 50,
child: Container(
child: Text("Text is Located here"),
),
),
],
),
)
],
),
Any help would be appreciated. Thanks
The error is occuring because you wrapped the Stack widget with Container which expands to the entire screen, if not provided height or width. So, just provide a custom height to the Container that will fix the overflow error. Working code below:
body: Column(
children: <Widget>[
Container(
color: Colors.blue,
height: 200,
child: Stack(
children: <Widget>[
Positioned(
top: 100,
left: 50,
child: Container(
child: Text("Text is Located here"),
),
),
],
),
)
],
),
I provided a test height. You may need to provide height or width per your requirement.
Hope this answers your question.
Please try below code:-
body: Column(
children: <Widget>[
Positioned(
top: 100,
left: 50,
child: Container(
child: Text("Text is Located here"),
),
),
],
),

Expand widgets inside the Stack widget

I have a stack widgets with two widgets inside.
One of them draws the background, the other one draws on top of that.
I want both widgets to have the same size.
I want the top widget, which is a column, to expand and fill the stack vertically to the size that is set by the background widget.
I tried setting the MainAxis mainAxisSize: MainAxisSize.max but it didn't work.
How can I make it work?
Use Positioned.fill
Stack(
children: [
Positioned.fill(
child: Column(
children: [
//...
],
),
),
//...
],
);
More info about Positioned in Flutter Widget of the Week
How does it work?
This is all about constraints. Constraints are min/max width/height values that are passed from the parent to its children. In the case of Stack. The constraints it passes to its children state that they can size themselves as small as they want, which in the case of some widgets means they will be their "natural" size. After being sized, Stack will place its children in the top left corner.
Positioned.fill gets the same constraints from Stack but passes different constraints to its child, stating the it (the child) must be of exact size (which meant to fill the Stack).
Positioned.fill() is the same as:
Positioned(
top: 0,
right: 0,
left: 0,
bottom:0,
child: //...
)
For even more examples and info: How to fill a Stack widget and why? and Understanding constraints.
You can try wrapping the Column with a positioned widget. Set top to 0 and bottom to 0. This will make the column fill the stack vertically.
sample code:
Stack(
children: <Widget>[
// Background widget rep
Container(
color: Colors.pink,
),
Positioned(
top: 0,
bottom: 0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('madonna'),
Text('flutter'),
],
),
)
],
)
I think you could wrap you column in a container like this:
Container(
height: double.infinity,
width: double.infinity,
child: Column()
),
The accepted answer did not answer my issue completely. So, I put my code here in case you have a similar issue.
class NoContentView extends StatelessWidget {
const NoContentView({Key? key, required this.message}) : super(key: key);
final String message;
#override
Widget build(BuildContext context) {
return Expanded(
child: Stack(
children: [
Positioned.fill(
child: FittedBox(
child: const Image(image: AssetImage(AppImages.noReceiptsWeb), fit: BoxFit.fitWidth),
),
),
MessageView(message: message),
],
),
);
}
}
In my case, I thought that I needed to expand the container in the light blue color with an expanded widget inside the stack widget.
Problems arose, especially since I was adding the stack widget in the column widget, and the way to make the container double.infinity dimensions I definitely had a problem with the vertical axis.
In the end, I managed to show it like this photo...
Column(
children: [
//filter
Container(
color: orange,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Text(
'All',
style: getRegular(color: white.withOpacity(.6)),
),
),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 10, 0),
child: Text(
'Ready',
style: getRegular(color: white.withOpacity(.6)),
),
),
freeh(),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
],
),
Row(
children: [
Icon(
filter,
color: white.withOpacity(.7),
size: 20,
),
Text(
'FILTER',
style: getLight(
color: white.withOpacity(.7),
),
),
freeh(),
],
),
],
),
),
Expanded(
child: Stack(
alignment: Alignment.topLeft,
children: [
Container(
color: lightBlue, //here to use map>>>>
),
Container(
height: 35,
width: 120,
margin: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: primary,
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
FontAwesomeIcons.listUl,
color: white.withOpacity(.8),
size: 20,
),
Text(
'List View',
style: getRegular(color: white.withOpacity(.8)),
)
],
),
),
],
),
)
],
),