Inside a card I have a stack with 1) an image and 2) a text inside a container.
How can I make the container width to fill the card width?
Card(
clipBehavior: Clip.antiAlias,
child: Stack(
children: <Widget>[
Positioned.fill(child: Image.network(
image_url,
fit: BoxFit.fitWidth,
),
),
Positioned(
bottom: 0,
child: Container(
padding: new EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0),
decoration: new BoxDecoration(color: Colors.black12),
child: Row(
children: <Widget>[
Text("test1"),
Text("test2"),
Text("test3"),
],
),
),
),
],
)
);
Set the left and right values to 0 so that the container will behave so.
Card(
clipBehavior: Clip.antiAlias,
child: Stack(
children: <Widget>[
Positioned.fill(child: Image.network(
image_url,
fit: BoxFit.fitWidth,
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
padding: new EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0),
decoration: new BoxDecoration(color: Colors.black12),
child: Row(
children: <Widget>[
Text("test1"),
Text("test2"),
Text("test3"),
],
),
),
),
],
)
);
Wrap all the childrens with the Expanded widget.
Row(
children: <Widget>[
Expanded(
child: Text("test1")
),
Expanded(
child: Text("test2")
),
Expanded(
child: Text("test3")
),
],
),
From the Expanded Widget Documentation:
Using an Expanded widget makes a child of a Row, Column, or Flex expand to fill the available space in the main axis (e.g., horizontally for a Row or vertically for a Column). If multiple children are expanded, the available space is divided among them according to the flex factor.
Related
I want the text to adjust vertically with 2 lines as the limit, and the rest be a ... but maxLines didn't work
How it looks
How I want it to look
This is my code:
Container(
margin: const EdgeInsets.symmetric(vertical: 20.0),
height: 150.0,
child: ListView(
// This next line does the trick.
scrollDirection: Axis.horizontal,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
child: Column(children: [
Row(
children: [
Stack(
children: [
ClipRRect(
borderRadius:
BorderRadius.circular(8.0),
child: Image.network(
videos[1].thumbnailUrl,
height: 80,
width: 150,
fit: BoxFit.fill,
),
),
],
),
],
)
]),
),
Flexible(
child: Text(
videos[1].title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
)),
],
),
How do I fix this error
Your column does not have an horizontal limit and can expand indefinitely, you have to define a width to limit your text, I recommend you to wrap your entire column inside a SizedBox, then adjust the image fit to always fit that size and then maxLines will work.
try this you need just to put container width to overflow the text
return Container(
margin: const EdgeInsets.symmetric(vertical: 20.0),
height: 150.0,
color: Colors. yellow,
child: ListView.builder(
// This next line does the trick.
scrollDirection: Axis.horizontal,
itemCount: 4,
itemBuilder: (context, index) {
return SizedBox(
width: 150,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: Colors.red,
child: Column(children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
children: [
ClipRRect(
borderRadius:
BorderRadius.circular(8.0),
child: Image.network(
videos[1].thumbnailUrl,
height: 80,
width: 150,
fit: BoxFit.fill,
),
),
],
),
],
)
]),
),
const Expanded(
child: Text(
videos[1].thumbnailUrl,
maxLines: 2,
overflow: TextOverflow.ellipsis,
)),
],
),
);
},
))
If you used Flexible, the text would fit in 1 line. Change Flexible to Extended then maxline and overflow will work.
I've been trying to achieve this alignment in a flutter AppBar:
I tried doing it in multiple ways, with Flex (which didn't really work, all the widget got clustered together) and with static paddings...
Flex:
Don't know why my sizedBoxes expand... Also I don't know how to align the button, dropdown and drawer to the left...
AppBar(
backgroundColor: Theme.of(context).colorScheme.background,
automaticallyImplyLeading: false,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
fit: FlexFit.tight,
flex: 4,
child: Container(
color: Theme.of(context).colorScheme.onPrimary,
child: Column(
children: const [
Image(
fit: BoxFit.contain,
image: AssetImage('assets/images/danube_logo.png'),
),
],
),
),
),
Flexible(
fit: FlexFit.tight,
flex: 6,
child: Container(
color: Theme.of(context).colorScheme.onPrimary,
child: Column(
children: const [
Image(
fit: BoxFit.contain,
image: AssetImage('assets/images/eu_logo.png'),
),
],
),
),
),
const Flexible(
fit: FlexFit.tight,
flex: 2,
child: MyTripsButton(),
),
const Flexible(
fit: FlexFit.tight,
flex: 2,
child: LanguageSelector(),
),
const Flexible(
fit: FlexFit.tight,
flex: 2,
child: DrawerMenuButton(),
),
],
),
);
Paddings, kinda work but not the best solution...:
AppBar(
backgroundColor: Theme.of(context).colorScheme.background,
automaticallyImplyLeading: false,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(left: 13.0, right: 130.0),
child: Container(
color: Theme.of(context).colorScheme.onPrimary,
child: Column(
children: const [
Image(
fit: BoxFit.contain,
image: AssetImage('assets/images/danube_logo.png'),
),
],
),
),
),
Container(
color: Theme.of(context).colorScheme.onPrimary,
child: Column(
children: const [
Image(
fit: BoxFit.contain,
image: AssetImage('assets/images/eu_logo.png'),
),
],
),
),
Padding(
padding: const EdgeInsets.only(right: 25.0),
child: const MyTripsButton(),
),
Padding(
padding: const EdgeInsets.only(right: 50.0),
child: const LanguageSelector(),
),
Padding(
padding: EdgeInsets.only(
right: 30.0,
),
child: DrawerMenuButton()),
],
),
);
Am I going around this the wrong way?
Just use two row widgets. Wrap your 2 left widgets within one row and other widgets in the second row. After this wrap both of your rows into a parent row and give the property of spaceBetween. Not the best solution but it will work
I created two container in a row and want it in center of the screen so i used padding for it, but they more are close to each other, i want to add space between them. here is the snap of output.
Code:
Padding(
padding: EdgeInsets.fromLTRB(40, 250, 30, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Flexible(
flex: 2,
child: Container(
decoration: BoxDecoration(
color: Colors.pink,
borderRadius: BorderRadius.all(Radius.circular(3))),
height: 50,
width: 190,
child: Center(
child: Column(
children: <Widget>[
FlatButton(onPressed: (){}, child: Text("in",style:TextStyle(fontSize: 20))),
],
),
),
),
),
new Flexible(
flex: 2,
child: Container(
decoration: BoxDecoration(
color: Color(int.parse(presentcolor)),
borderRadius: BorderRadius.all(Radius.circular(3))),
height: 50,
width: 190,
child: Center(
child: Column(
children: <Widget>[
FlatButton(onPressed: (){}, child: Text("out",style:TextStyle(fontSize: 20))),
],
),
),
),
),
Use a Spacer or a SizedBox between 2 widgets.
Other option is to set mainAxisAlignment of Row to MainAxisAlignment.spaceBetween.
I started using the Gap package for adding spaces between widgets in rows or columns. Basically you just specify how big the space should be, so an 8px gap would be Gap(8).
Row(
children: [
widget1(),
Gap(8),
widget2(),
]);
The syntax is easy to use and there are special widgets like the MaxGap or SliverGap for specific use cases.
for centering this you can use Center() widget instead of padding and for putting space between the two you can add margin for the first one from the left. the code will be like this:
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Flexible(
flex: 2,
child: Container(
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.pink,
borderRadius: BorderRadius.all(Radius.circular(3))),
height: 50,
width: 190,
child: Center(
child: Column(
children: <Widget>[
FlatButton(onPressed: (){}, child: Text("in",style:TextStyle(fontSize: 20))),
],
),
),
),
),
new Flexible(
flex: 2,
child: Container(
decoration: BoxDecoration(
color: Color(int.parse(presentcolor)),
borderRadius: BorderRadius.all(Radius.circular(3))),
height: 50,
width: 190,
child: Center(
child: Column(
children: <Widget>[
FlatButton(onPressed: (){}, child: Text("out",style:TextStyle(fontSize: 20))),
],
),
),
),
),
you can change righ margin to the suitable value for you.
This is the easiest way to add "Text" containing 4 spaces or or however many spaces you like:
Row(
children: [
Flexible(),
Text(" "),
Flexible(),
]);
Need to show image above other image outside the widget margin.
I tried using stack, but it not coming outside.
Stack(children: <Widget>[
Container(child: Image.asset('assets/discover.png')),
Row(
children: <Widget>[
Expanded(child: Text(''), flex: 9),
Expanded(
child: ClipRRect(
borderRadius: new BorderRadius.circular(80.0),
child: Image.asset('assets/user.jpg')),
flex: 6,
),
Expanded(child: Text(''), flex: 9)
],
),
]);
Below source code works for your scenario. You have to give top padding for the image's container and make the entire stack's alignment as topCenter.
Additional things:
Consider giving height and width for the circled image.
Keep the big image widget in AspectRatio widget to occupy the full width of its parent widget and give fit property as well for showing entire image in the right fit.
.
Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 40),
child: AspectRatio(aspectRatio: 1, child: Image.asset('assets/discover.png', fit: BoxFit.cover),),
),
ClipRRect(
borderRadius: new BorderRadius.circular(40.0),
child: Image.asset('assets/user.jpg', height: 80, width: 80),
),
],
)
return Scaffold(
appBar: AppBar(
title: const Text('Flutter demo'),
),
body: Container(
padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
alignment: Alignment.topCenter,
child: Stack(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 30),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.network(
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQGLanNnFsLi3QnQFdh-k-mkwG6yrEEXhorSoElObizTnP0_8rR')),
),
Align(
alignment: Alignment.topCenter,
child: CircleAvatar(
radius: 30.0,
backgroundImage: NetworkImage(
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSIekuJOwtOWtZl9QX3t46Yz_7RCZ4Kpebnugsst2OFfNl-SGjf'),
backgroundColor: Colors.grey,
),
)
]),
));
Stack(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 50.0),
child: Image.network(
'https://cdn.pixabay.com/photo/2015/06/19/21/24/the-road-815297__340.jpg'),
),
Row(
children: <Widget>[
Expanded(child: Text(''), flex: 9),
Expanded(
child: ClipRRect(
borderRadius: new BorderRadius.circular(80.0),
child: Image.asset('assets/ic_profile.png'),
),
flex: 6,
),
Expanded(child: Text(''), flex: 9)
],
)
]),
I need a Container to be the size of its contents. It is currently the correct width but the height is too much because the Container is inside an Expanded, therefore the Container takes the height of the Expanded. Is it possible to fix this?
It doesn't help if you set the height of the container.
The page with the Expanded:
Column(
children: <Widget>[
Expanded(
child: Container(
child: Column(
children: <Widget>[
Expanded(
child: Container(
color: Colors.blue,
child: SmallContainers(),
),
flex: 2),
Expanded(
child: Container(
color: Colors.red,
child: OtherContainers(),
),
flex: 3),
],
),
),
flex: 1),
],
),
The page with the smaller Containers that I need its height smaller:
Container(
color: Colors.green,
child: Padding(
padding: EdgeInsets.all(12.0),
child: Text("Different content"),
),
),
You can try use SizedBox
SizedBox(
width: 200.0,
height: 300.0,
child: Container(
color: Colors.green,
child: Padding(
padding: EdgeInsets.all(12.0),
child: Text("Different content"),
),
),
)
Instead of wrapping small containers with Expanded, wrap it with IntrinsicHeight widget. This widget sizes its child to the child's intrinsic height.
Sample code below:
IntrinsicHeight(
child: Container(
color: Colors.blue,
child: SmallContainers(),
),
),
Hope this answers your question.