Flutter Why is container width not honoured? - flutter

I'm trying to create a circle image. Unfortunately, the width of the container is not honoured and I can't figure out why. What am I missing?
Drawer _getDrawer(List<Job> data) {
return Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the Drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
_getDrawerHeader(),
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app
// ...
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
// Update the state of the app
// ...
},
),
],
),
);
}
DrawerHeader _getDrawerHeader() {
return DrawerHeader(
child: StreamBuilder(
stream: FirebaseAuth.instance.currentUser().asStream(),
builder: (context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.hasData) {
return ListView(
children: <Widget>[
_getCircleImage(snapshot.data.photoUrl),
Text('test'),
Text('test'),
],
);
}
return Center(child: CircularProgressIndicator());
}),
decoration: BoxDecoration(
color: Colors.blue,
),
);
}
_getCircleImage(String url) {
return Container(
width: 64.0,
height: 64.0,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage(url),
fit: BoxFit.cover,
),
shape: BoxShape.circle,
),
);
}

That's a little tricky but it's how Flutter works, your Container doesn't know the constraints of the Parent, then It try to fill all the space available.
You can fix it adding an Align Widget
_getCircleImage(String url) {
return Align(
alignment: Alignment.centerLeft,
child: Container(
width: 64.0,
height: 64.0,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage(url),
fit: BoxFit.cover,
),
shape: BoxShape.circle,
),
),
);
}
More info : https://docs.flutter.io/flutter/widgets/Container-class.html

A widget can decide its own size only within the constraints given to it by its parent. This means a widget usually can’t have any size it wants.
A widget can’t know and doesn’t decide its own position on the screen, since it’s the widget’s parent who decides the position of the widget.
The parent widget takes the entire space available to draw the widget, Here Container is the parent widget, and it's taking whatever space is available, so to give heigh/width to the Container, that needed to be placed inside any widget which assigns x,y position of widgets to get it to draw.
So as per the above description, Container should have a parent that aligns Container on the screen.
Ex: Use
Align(
alignment: Alignment.center,
child: Container(),
);
OR
Center(
child: Container(),
);

Problem:
Container's constraints wont' have any impact if the passed constraints were tight.
For example:
SizedBox.fromSize(
size: Size.fromRadius(100), // Tight constraints are passed to the Container below
child: Container(
width: 100, // No impact
height: 100, // No impact
color: Colors.blue,
),
)
Solutions:
You need to loose those tight constraints. There are multiple ways of doing it. I'm listing a few here:
Use UnconstrainedBox:
SizedBox.fromSize(
size: Size.fromRadius(100),
child: UnconstrainedBox( // <-- UnconstrainedBox
child: Container(
width: 100, // Works
height: 100, // Works
color: Colors.blue,
),
),
)
Use Center or Align:
SizedBox.fromSize(
size: Size.fromRadius(100),
child: Center( // <-- Center
child: Container(
width: 100, // Works
height: 100, // Works
color: Colors.blue,
),
),
)
Use a Column or better Wrap:
SizedBox.fromSize(
size: Size.fromRadius(100),
child: Wrap( // <-- Wrap
children: [
Container(
width: 100, // Works
height: 100, // Works
color: Colors.blue,
),
],
),
)

Related

How to reposition a fixed widget in flutter

I'm building an AR app with Flutter and using the ar_flutter_plugin.
The position of the AR widget seems to be fixed to the top left and it doesn't move anywhere else. Whatever the other widgets in the tree, doesn't change anything. It's always at top left corner (see image).
It works with a dummy widget just fine (compare second img).
Child Ar widget
Widget build(BuildContext context) {
return SizedBox(
width: widget.width,
height: widget.height,
child: Column(
children: [
Expanded(
child: Column(children: [
Expanded(
child: ARView(
onARViewCreated: onARViewCreated,
planeDetectionConfig:
PlaneDetectionConfig.horizontalAndVertical,
),
),
Align(
alignment: Alignment(1, 1),
child: FloatingActionButton(onPressed: takePicture))
]),
),
],
));
}
Parent Widget
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Title'),
),
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
body: SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Stack(
children: [
Container(
width: 350,
height: 350,
child: ObjectsOnPlanesWidget(
// child: custom_widgets.ArPlaceholder(
width: double.infinity,
height: double.infinity,
modelUrl: widget.modelUrl,
),
),
Align(
alignment: AlignmentDirectional(-0.23, -0.92),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(8, 24, 8, 24),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color:
FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Icon(
Icons.chevron_left,
color: Colors.black,
size: 24,
),
),
),
Text(
'Try On',
style: FlutterFlowTheme.of(context).bodyText1,
),
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color:
FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.share_outlined,
color: Colors.black,
size: 24,
),
),
],
),
),
),
Align(
alignment: AlignmentDirectional(0, 0.95),
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.photo_camera,
color: Colors.black,
size: 24,
),
),
),
],
),
),
),
);
}
I want to put the camera in the background and put other widgets (such as photo-taking-button) on top of it.
How do I reposition it into a container? At least under the App Bar?
Logically this should have worked, what i would suggest you try would be to first have a SafeArea widget.
SafeArea(
child: build(buildContext),
),
I had a similar issue in the past and using this solved it.
Also, there seems to be an open issue which seems related to this with the following possible solution :
With Flutter 2.10.5. it works without problems. This seems to be a Flutter 3 problem.
The way platforms views are rendered was changed in the 3.0 release.
probably same issue:
flutter/flutter#106246
explained here:
flutter/flutter#103630
I hope this will be fixed in new Flutter 3 releases soon.
And also this
I try the master channel Flutter v3.1.0-0.0.pre.1372 and the issue is fixed there.
Fixed will come to a stable channel soon with Flutter v3.1.0.
Also, I am not sure why are you using SizedBox as your parent widget.
Why not try a basic Container instead?
Good luck, Let me know if I can help with anything else

Height adjustment of an Image in a row inside a Card

my idea is to create a card widget that has an image on the left and corresponding text data on the right side. The picture should always take the full height and 1/3 of the width (I used expanded with flex to get this. Not sure if this is the best way). The image should be placed in a stack in order to stack further widgets.
My problem is that I am not able to place the image in the stack without specifying a fixed height. I tried Positoned.fill but this did not work for me.
This is my code so far for the card:
Widget build(BuildContext context) {
return Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Row(
children: [
Expanded(
child: Stack(
children: [
Container(
// child: Positioned.fill(
// child: ClipRRect(
// borderRadius: BorderRadius.circular(15.0),
// child: Image(
// image: AssetImage("assets/eyes.jpg"),
// fit: BoxFit.cover,
// ),
// ),
// ),
),
],
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.grey,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("This is a test"),
SizedBox(height: 10),
Text("This is a test test"),
SizedBox(height: 10),
Text("This is a test test test"),
SizedBox(height: 10),
Text("This is a test test"),
SizedBox(height: 10),
Text("This is a test"),
],
),
),
),
),
],
),
);
}
Here is a picture of the current state. The image should take up the entire white area on the left side of the card.
Instead of adding a child image widget inside your container, you can add a decoration image to the container itself. Here's how you do it:
Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage("url"),
),
),
),

Efficient way to make container take remaining width in a Row widget in Flutter

I am new to Flutter and was practicing its UI where I came across a situation where I had a list where each list element have an image on the left and some text on right.
Below is my approach to that
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 20),
children: [
const SizedBox(height: 5),
Row(
children: [
Container(
height: 80,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: const DecorationImage(
image: NetworkImage('http://images.unsplash.com/photo-1555010133-d883506aedee?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max'),
fit: BoxFit.cover
)
),
),
const SizedBox(width: 10),
Container(
color: Colors.green,
height: 80,
width: 280,
)
],
),
],
),
Here I am specifying width individually for both containers which is not an efficient way to do this since phone sizes may vary.
Below is the result for above block of code
Screenshot of the app screen
I tried specifying crossAxisAlignment: CrossAxisAlignment.stretch to the Row() but it throws an error as below
The following assertion was thrown during performLayout():
BoxConstraints forces an infinite height.
How can I achieve this? Please assist
Thank you
Wrap the widget with an Expanded inside the row:
Row(
children: [
...otherChildren,
Expanded(
child: Container(
color: Colors.green,
height: 80,
),
),
],
),
Use ListView.builder with ListTile widgets. It has a leading widget (normally an icon or an avatar) to the left, text in the middle and trailing widget (normally an icon), each of which is optional.
ListView.builder(
itemCount: ...,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: const CircleAvatar(
radius: 20.0,
foregroundImage: NetworkImage(...),
),
title: Text(...),
subtitle: Text(...),
trailing: ...,
onTap: () => ...,
);
},
)

Flutter position widget with top or left throws error

StreamBuilder
Listview.builder
Card(
child: Container(
width: double.infinity,
padding: EdgeInsets.all(10),
child: Column(
children: [
CardMenuTitle(id: menu.title),
CardMenuImage(menu: menu, index: index),
... ]
...
Now in cardmenuimage
Widget build(BuildContext context) {
return Stack(
children: [
Container(), //just tried to add empty container to see if it fixes the problem
Positioned(
top: 1, //if I remove this line, it works,
child: Container(
width: double.infinity,
// needed
color: Colors.transparent,
child: Image.asset(
"assets/images/menu/${menu.image}",
fit: BoxFit.cover,
),
),
),
Positioned.fill(
child: Material(
color: Colors.transparent,
child: InkWell(
splashColor: Colors.black.withOpacity(0.5),
onTap: () {
}, // needed
),
),
),
],
);
}
}
The following assertion was thrown during performLayout():
BoxConstraints forces an infinite width.
These invalid constraints were provided to _RenderColoredBox's layout() function
by the following
function, which probably computed the invalid constraints in question:
RenderConstrainedBox.performLayout
(package:flutter/src/rendering/proxy_box.dart:279:14)
The offending constraints were:
BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
Positioned(
top: 1, //if I remove this line, it works,
child: Container( //removing container solves the problem but image is not displayed
width: double.infinity,
// needed
color: Colors.transparent,
child: Image.asset(
"assets/images/menu/${menu.image}",
fit: BoxFit.cover,
),
),
),
After removing the container from the position widget, the error goes away but image is not displayed.
replace width: double.infinity with width: MediaQuery.of(context).size.width

Building grid layouts with Flutter

I am very new at Flutter and was confused with how to use the widgets to create a sustainable replacement for Native Androids, RelativeLayout and ConstraintLayout but was not able to use the Column, Row widgets appropriately. I am trying to build this layout but wasn't able to up until now.
I have started by adding a container for the entire thing, then a column for every 'block' and then use Rows/Containers for the rest of them. Here is the code I have written up until now but this doesn't show anything:
Container(
height: 250,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: colorItems // a color list at global scope with 2 items
),
color: Colors.black
),
)
],
),
),
)
Edit
Please give an explanation of your hierarchy of widgets like this:
Container
- Column
- Row
I added a full example of what you are trying to get:
Below is how the widget tree should look like:
WIDGET HEIRARCHY
Container
- Column
- Container
- SizedBox
- Expanded
-Row
- Container
- SizedBox
-Expanded
- Column
- Container
- SizedBox
- Expanded
- Row
- Expanded
- Container
- Expanded
- Container
- Expanded
- Container
CODE
class StackOver extends StatelessWidget {
final BoxDecoration _boxDecoration = BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(
15.0,
),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Tab bar',
),
),
body: Padding(
padding: const EdgeInsets.all(10.0),
// parent container housing all other widgets
child: Container(
height: 250,
child: Column(
children: [
// frist container [give it a height, it takes up the width of the parent]
Container(
height: 80,
decoration: _boxDecoration,
),
// add spacing
SizedBox(
height: 15,
),
// second child of the column [consists of a Row with children]
Expanded(
child: Row( // row
children: [
Container( // first child
width: 80, // give it a width, it takes up the height of parent since it is wrapped with an expanded widget
decoration: _boxDecoration,
),
// add spacing
SizedBox( // second child
width: 15,
),
Expanded( // thrid child [consists a column with children ]
child: Column(
children: [
Container(
height: 80, // give it a height, it takes up the width of parent since it is wrapped with an expanded widget
decoration: _boxDecoration,
),
// add spacing
SizedBox( // second child
height: 20,
),
Expanded( // third child [consists of a row with 3 containsers]
child: Row(
children: [
Expanded( // first container
child: Container(
decoration: _boxDecoration,
),
),
// add spacing
SizedBox(
width: 15,
),
Expanded( // second container
child: Container(
decoration: _boxDecoration,
),
),
// add spacing
SizedBox(
width: 15,
),
Expanded( // third container
child: Container(
decoration: _boxDecoration,
),
),
],
),
),
],
),
),
],
),
),
],
),
),
),
);
}
}
OUTPUT