I want the Container to take the height of the Card.
I have tried many Widgets but failed to fulfill my order,
I tried to use Flexible as a parent for the container but to no avail.
I have this code:
Card(
color: Color(0xff8c6ac9),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text2'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text3'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text4'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text5'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text6'),
),
],
),
),
Container(
decoration: BoxDecoration(
color: Color(0xff9778ce),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10),
topRight: Radius.circular(10))),
child: Column(
children: <Widget>[
Icon(
Icons.delete,
color: Colors.white,
),
Icon(
Icons.edit,
color: Colors.white,
),
],
mainAxisAlignment:
MainAxisAlignment.spaceAround,
),
width: 40,
),
],
),
)
The output of this code is:
And what I want is:
Edit: The Card widget it is an item in ListView widget.
Thanks...
You're almost there... wrap your row with an IntrinsicHeight widget
Card(
color: Color(0xff8c6ac9),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text2'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text3'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text4'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text5'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text6'),
),
],
),
),
Container(
decoration: BoxDecoration(
color: Color(0xff9778ce),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10),
topRight: Radius.circular(10))),
child: Column(
children: <Widget>[
Icon(
Icons.delete,
color: Colors.white,
),
Icon(
Icons.edit,
color: Colors.white,
),
],
mainAxisAlignment:
MainAxisAlignment.spaceAround,
),
width: 40,
),
],
),
),
),
You can use the IntrinsicHeight widget since your Card doesn't have a predefined height.
A widget that sizes its child to the child's intrinsic height.
This class is useful, for example, when unlimited height is available and you would like a child that would otherwise attempt to expand infinitely to instead size itself to a more reasonable height.
Note: This class is relatively expensive, because it adds a speculative layout pass before the final layout phase. Avoid using it where possible. In the worst case, this widget can result in a layout that is O(N²) in the depth of the tree.
ListView.builder(
itemBuilder: (context, index) {
// wrapped the card widget with an intrinsic height
return IntrinsicHeight(
child: Card(
color: Color(0xff8c6ac9),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text2'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text3'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text4'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text5'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Text6'),
),
],
),
),
Container(
decoration: BoxDecoration(
color: Color(0xff9778ce),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10),
topRight: Radius.circular(10))),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(
Icons.delete,
color: Colors.white,
),
Icon(
Icons.edit,
color: Colors.white,
),
],
mainAxisAlignment: MainAxisAlignment.spaceAround,
),
width: 40,
),
],
),
),
);
},
),
OUTPUT:
Related
I am trying to build a layout with basically 2 parts which one is scrollable and not the other. I have a button on the not scrollable one but it is not clickable
Here is the code
Scaffold(
body: Stack(
children: [
Container(
height: double.infinity,
decoration:
const BoxDecoration(color: AppColors.secondaryBackground),
child: const SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: ReturnButton(),
),
),
),
SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 150.0),
child: Container(
width: double.infinity,
decoration: const BoxDecoration(
color: AppColors.mainBackground,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25))),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 20.0),
child: Column(children: const []))),
),
)
],
),
);
try using Icon Button Instead, and provide it with the Icon and inPressed callback
IconButton(
iconSize: 72,
icon: const Icon(Icons.arrow_left),
onPressed: () {
// ...
},
),
Im trying to do the layout below with flexible widgets so when the screen size changes the layout stays about the same but when I put a flexible widget around a column anything that I put in the column in not visible. What am I doing wrong?
Wanted Outcome
What I have
My code
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.black,
),
body: SafeArea(
child: Column(
children: [
Flexible(
flex: 9,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.grey,
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(),
),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(),
),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(),
),
],
),
),
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white),
),
)
],
),
),
);
}
}
Finish your work, you will get the thing you have asked
Provide child on container
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.grey,
),
child: SizedBox(
height: 50,
width: double.infinity,
),
),
),
I want to show an image in a ListTile widget which should looks something like this.
Here is my code:
Padding(
padding: EdgeInsets.symmetric(vertical: 0.0, horizontal: 20.0),
child: Card(
color: Colors.white,
child: ListTile(
leading: Container(
child: Image.network((orientation == Orientation.portrait
? image.portrait
: image.landscape),
fit: BoxFit.cover)
),
title: Text(terms[index].title),
subtitle: Text(terms[index].videoNumber.toString() + " Videos"),
trailing: Icon(
Icons.arrow_forward_ios,
color: Colors.lightBlueAccent,
),
),
),
);
This results in below output
What should I do so the image looks spread out as above.
You can set the padding of ListTile to 0:
...
child: ListTile(
contentPadding: EdgeInsets.all(0),
leading: ...
);
But even so, you can see that the leading only take the upper half, not the entire height of the card:
...
Card(
color: Colors.blue,
child: ListTile(
contentPadding: EdgeInsets.all(0),
leading: ...
Which result in:
You can use a Stack to include both ListTile and the leading Icons but lots of things have to be hardcorded. In this case, I recommend using ClipRRect with Row:
Padding(
padding: EdgeInsets.symmetric(
vertical: 0.0, horizontal: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
height: 70,
color: Colors.white,
child: Row(
children: <Widget>[
Container(
color: Colors.red,
width: 70,
height: 70,
child: Icon(Icons.cake, color: Colors.white),
),
SizedBox(width: 10),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text('Test Title'),
Text('Test Video',
style: TextStyle(color: Colors.grey))
],
),
),
Icon(Icons.arrow_forward_ios,
color: Colors.blue),
],
),
),
),
);
Result:
Widget buildCard(_user) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
child: Card(
color: Colors.blue.shade100,
child: Row(
children: <Widget>[
Container(
margin: const EdgeInsets.all(0),
decoration: BoxDecoration(
color: Colors.blue.shade200,
shape: BoxShape.rectangle,
borderRadius:const BorderRadius.only(
topLeft: Radius.circular(4.0),
bottomLeft: Radius.circular(4.0),
),
),
width: 20,
height: 73,
),
const SizedBox(width: 10),
Expanded(
child: ListTile(
title: Text('${_user.state?.email!.substring(0, 6)}'),
subtitle: Text('${_user.state?.createdAt}'),
),
),
//const Icon(Icons.arrow_forward_ios, color: Colors.blue),
],
),
),
),
);
}
I have two widgets which are basically the same, except their color. They are list tile in list view builder. There is a checking to show in grey or red. The only property to be changed is color. I know that there is copyWith() function, but it seems that cannot be used in this case.
How can I reuse the below widget?
Widget listTile = Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8.0, 0),
child: ListTile(
title: Text(
message.title),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(message.name),
Row(
children: <Widget>[
Icon(
Icons.alarm_on,
color: Colors.redAccent,
size: 16,
),
Text(message.time),
],
)
],
),
),
),
),
);
Make a function which takes the color as a parameter..and return your widget from that function..
Something like this..
customWidget( Color color){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8.0, 0),
child: ListTile(
title: Text(
message.title),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(message.name),
Row(
children: <Widget>[
Icon(
Icons.alarm_on,
//color: Colors.redAccent,
color: color,
size: 16,
),
Text(message.time),
],
)
],
),
),
),
),
);
}
And whenever you want to use it..do it this way..
customWidget(Colors.red)
Hope it solves your issue..feel free to ask for clarifications :)
Instead of making it a variable, you can make it a method and then pass the color parameter to it.
Widget buildWidget(Color color) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
color: color, // Use your color parameter here
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8.0, 0),
child: ListTile(
title: Text(
message.title),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(message.name),
Row(
children: <Widget>[
Icon(
Icons.alarm_on,
color: Colors.redAccent,
size: 16,
),
Text(message.time),
],
)
],
),
),
),
),
);
}
You can also pass along the message object you are using as a parameter to the function
So your ListView.builder will look like:
ListView.builder(
..., // other properties
itemBuilder: (context, index) => buildWidget(/*Your params here*/),
),
I'm trying to put a horizontal line(currently Divider but could be changed as a CustomPaint) as a background of a Row. However, regardless of the order of children, the line always goes front of the Row. I can't figure out what's wrong. Here's the code.
Stack(
children: <Widget>[
Positioned.fill(
child: const Divider(color: Colors.black),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Ink(
decoration: ShapeDecoration(
color: Colors.grey[350],
shape: CircleBorder(),
),
child: Padding(
padding: const EdgeInsets.all(4),
child: Icon(Icons.arrow_forward, size: 32)
),
),
Ink(
decoration: ShapeDecoration(
color: Colors.grey[350],
shape: CircleBorder(),
),
child: Padding(
padding: const EdgeInsets.all(4),
child: Icon(Icons.location_on, size: 32)
),
),
Ink(
decoration: ShapeDecoration(
color: Colors.grey[350],
shape: CircleBorder(),
),
child: Padding(
padding: const EdgeInsets.all(4),
child: Icon(Icons.flag, size: 32)
),
),
],
),
],
),
and here's the result image.
Use Container instead of Ink
Stack(
children: <Widget>[
Positioned.fill(
child: const Divider(color: Colors.black),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
decoration: ShapeDecoration(
color: Colors.grey[350],
shape: CircleBorder(),
),
child: Padding(
padding: const EdgeInsets.all(4),
child: Icon(Icons.arrow_forward, size: 32)
),
),
Container(
decoration: ShapeDecoration(
color: Colors.grey[350],
shape: CircleBorder(),
),
child: Padding(
padding: const EdgeInsets.all(4),
child: Icon(Icons.location_on, size: 32)
),
),
Container(
decoration: ShapeDecoration(
color: Colors.grey[350],
shape: CircleBorder(),
),
child: Padding(
padding: const EdgeInsets.all(4),
child: Icon(Icons.flag, size: 32)
),
),
],
),
],
);