I have this class State:
class _ItemCardState extends State<ItemCard> {
double imgSize = 30;
Axis expanded = Axis.horizontal;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
expanded =
expanded == Axis.horizontal ? Axis.vertical : Axis.horizontal;
imgSize = imgSize == 30 ? 200 : 30;
});
},
child: Card(
margin: const EdgeInsets.all(5.0),
child: Padding(
padding: const EdgeInsets.all(15),
child: Flex(
direction: expanded,
children: [
Image.network(
'http://cdn.shopify.com/s/files/1/0565/0697/4379/articles/Cafe-expresso-sin-maquina_1200x1200.jpg?v=1621619617',
width: imgSize,
),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(widget.product['name'],
style: const TextStyle(fontSize: 20)),
Text(widget.product['price'] + ' \$',
style: const TextStyle(fontSize: 15)),
],
),
Text(widget.product['ingredients'],
style: const TextStyle(fontSize: 15, color: Colors.grey)),
],
),
],
),
),
),
);
}
}
I want the Flex Widget change direction onTap, it works.
But the column inside is not taking all space avaible in the crossAxis.
If I put an Expanded Widget it stops working,...
I've tried Flexibles, but somehow it didnt work.
I used ListTiles also, but I couldnt make it work.
Any idea on how to do it?
well. I resolved it putting the Flex Widget inside a SizedBox and then I was able to use Flexible>fit:FlexFit.tigth:
SizedBox(
height: 300,
child: Flex(
direction: expanded,
children: [
Image.network(
'http://cdn.shopify.com/s/files/1/0565/0697/4379/articles/Cafe-expresso-sin-maquina_1200x1200.jpg?v=1621619617',
width: imgSize,
),
Flexible(
fit: FlexFit.tight,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(widget.product['name'],
style: const TextStyle(fontSize: 20)),
Text(widget.product['price'] + ' \$',
style: const TextStyle(fontSize: 15)),
],
),
Text(widget.product['ingredients'],
style: const TextStyle(
fontSize: 15, color: Colors.grey)),
],
),
)
],
),
),
Related
I am opening a bottom model sheet, and want to implement a functionality that whenever I click on a icon, I get a snackbar. So i implemented it, but whenever I am clicking on the button, snackbar is coming under the bottom modal sheet, like when you lower the bottom model sheet, you can see snackbar popped there in previous screen. I want that snackbar should show above the modal sheet, visible to user while sheet is up. Please help me on this.
Here is the code -
class RouteItems extends StatelessWidget {
final int index;
final NodeElement data;
RouteItems({required this.index, required this.data});
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
SvgPicture.asset(
'assets/icons/road-straight-line-top-view.svg',
height: 15,
width: 80,
),
SvgPicture.asset(
filterRoutesIcon("${data.node?.type}"),
height: 30,
width: 30,
),
SvgPicture.asset(
'assets/icons/road-straight-line-top-view.svg',
height: 15,
width: 80,
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Container(
//height: 60,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: MediaQuery.of(context).size.width*0.625,
child: Text(
'${data.node?.name}',
style: TextStyle(fontSize: 12.0),
//overflow: TextOverflow.ellipsis,
),
),
Text(
data.eta!.getFormattedDate('hh:mm a, d MMM'),
style: TextStyle(fontSize: 10.0, color: colorDarkGrey),
)
],
),
),
),
],
),
Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Wrap(
children: [
Text(
'Bus is scheduled to arrive at ${data.eta!.getFormattedDate('hh:mm a, d MMM')} Bus is scheduled to depart at ${data.etd!.getFormattedDate('hh:mm a, d MMM')}'
),
],
),
),
);
},
child: Column(
children: [
Icon(
Icons.timer,
size: MediaQuery.of(context).size.width*0.04,
),
Text(
getStoppageTime(data.stoppage??0),
style: TextStyle(
fontSize: 10,
color: popUpLightTextColor,
),
),
],
),
),
),
],
),
);
}
}
What the problem is I have to render some texts which are in a row and also it should wrap when it doesn't have enough space but the row does not wrap.
I have used wrapping it Expanded, Wrap, and tried some stackoverflow answers but none of them work
Below is my code for it
Widget xyz(List _list) {
return Padding(
padding: const EdgeInsets.fromLTRB(50, 10, 40, 10),
child: InkWell(
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Title : ',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
),
Wrap(children: [
Row(children: [
for (int i = 0; i < _list.length; i++)
Container(
padding: const EdgeInsets.only(right: 8),
child: Text(
'${_list[i]}',
style: TextStyle(fontSize: 13),
),
),
]),
]),
],
),
),
);
}
class _Page3State extends State<Page3> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
xyz([
'Text1',
'Text2',
'Text3',
'Text4',
'Text5',
'Text6',
'Text7',
]),
//other widgets
],
),
);
}
}
And this is the output I am getting
I want the 'Text6' & 'Text7' Text widgets to go on the next line.
This is a working example:
The issues are incorrect Flexible (Expanded) placing, and your Wrap had a Row child instead of directly placed children.
Widget xyz(List _list) {
return Padding(
padding: const EdgeInsets.fromLTRB(50, 10, 40, 10),
child: InkWell(
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Title : ',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
),
Flexible(
child: Wrap(
children: [
for (int i = 0; i < _list.length; i++)
Container(
padding: const EdgeInsets.only(right: 8),
child: Text(
'${_list[i]}',
style: TextStyle(fontSize: 13),
),
),
],
),
),
],
),
),
);
}
class _Page3State extends State<Page3> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
xyz([
'Text1',
'Text2',
'Text3',
'Text4',
'Text5',
'Text6',
'Text7',
]),
//other widgets
],
),
);
}
}
Can anyone guide me how to achieve this in flutter?
Thanks
Here you go bro ..... Cheers !!!
class _MyHomePageState extends State<MyHomePage> {
double width;
double height;
int currentValue = 5;
Map<int,int> minutesCostMap = {
5: 20,
10 : 25,
15 : 30,
20 : 35,
},
#override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: Text("Chris Watson",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 19),),
),
Padding(
padding: const EdgeInsets.only(bottom: 25),
child: Text.rich(
TextSpan(children: [
TextSpan(text: "This "),
TextSpan(text: currentValue.toString() + " minutes ",style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: "session will cost you "),
TextSpan(text: minutesCostMap[currentValue].toString() + "\$",style: TextStyle(fontWeight: FontWeight.bold)),
])
),
),
Stack(
alignment: Alignment.center,
children: [
Container( /// GREY HORIZONTAL LINE
height: 10,width: width * 0.6,color: Colors.grey[350],
),
Container(
width: width * 0.6 + 50,
height: 50,
child: Row( /// ROW OF 4 CIRCLE WIDGETS PLACED ABOVE THAT LNE
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
checkpointButton(5,currentValue == 5),
checkpointButton(10,currentValue == 10),
checkpointButton(15,currentValue == 15),
checkpointButton(20,currentValue == 20),
],
),
),
//Positioned(left: 0,chil),
//Positioned(left: ,child: Container(decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.blue),width: 40,height: 40,)),
//Positioned(left: ,child: Container(decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.blue),width: 40,height: 40,)),
//Positioned(left: ,child: Container(decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.blue),width: 40,height: 40,)),
],
),
Padding(
padding: EdgeInsets.only(top: 25),
child: Container(
width: width * 0.75,
height: 40,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 1,
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.blue,width: 1.5)),
child: Center(child: Text("CANCEL",style: TextStyle(color: Colors.blue),),),
),
),
Container(width: 10,height: 5,),
Expanded(
flex: 2,
child: Container(color: Colors.blue,child: Center(child: Text("ACCEPT",style: TextStyle(color: Colors.white),),),),
),
],
),
),
),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget checkpointButton(int value,bool isActive){
return GestureDetector( /// THIS WILL DETECT A TAP EVENT ON THIS CIRCLE WIDGET
onTap: (){
setState(() {
currentValue = value; /// IF THE CURRENT VALUE IS SAME AS THE VALUE OF THE CIRCLE, IT WILL CHANGE ITS APPEARANCE TO SHOW THAT ITS ACTIVE
});
},
child: Container( /// CIRCLE PRESENT BEHIND PROVIDING THE BLUE BORDER
height: 50,width: 50,
decoration: BoxDecoration(shape: BoxShape.circle,border: Border.all(color: isActive ? Colors.blue : Colors.transparent,width: 1.5)),
child: Center(
child: Container( /// INNER CIRCLE CONTAINING THE VALUE
decoration: BoxDecoration(shape: BoxShape.circle,color: isActive ? Colors.blue : Colors.grey[350]),
width: 40,height: 40,
child: Center(child: Text(value.toString(),style: TextStyle(fontWeight: FontWeight.bold,color: isActive ? Colors.white : Colors.black),)),
)
)
)
);
}
}
Result :
Edit :
I have updated the code above to match your requirements. Basically what I did what I added a Map (minutesCostMap) which contains the list of the minutes and their corresponding cost.
Then moving on the the place where we are displaying the cost, you can see that I used the value from the map itself. So the value we are printing will output the cost with corresponds to the provided minutes(i.e. present in the currentValue variable)
I am unable to make my text stop extending the screen and overflowing. My code is as follows:
class OrderTileDisplay extends StatelessWidget {
final MenuOrderData orderItem;
final editable;
OrderTileDisplay(this.orderItem, {this.editable = true});
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
GestureDetector(
onTap: (){},
child: Container(
color: Colors.transparent,
margin: EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(
orderItem.quantity.toString() + 'x',
style: Title16,
),
SizedBox(
width: 8,
),
Text(
orderItem.name, // OVERFLOWS WHEN IT IS A LONGER SENTENCE
style: Title18bold,
overflow: TextOverflow.ellipsis,
),
],
),
Row(
children: [
editable? Icon(Icons.edit, color: Colors.grey[200], size: 20,) : Container(),
SizedBox(width: 8,),
Text("£" + Provider.of<CP>(context).getTotalForItem(orderItem).toStringAsFixed(2),
style: Title18bold,),
],
),
],
),
),
),
Container(... and other stuff)
I have tried putting Text inside a container then Expanded widget but I keep getting errors. Not sure how to solve it.
Try to wrap your Row and Text inside a Flexible:
Flexible( //flexible here
child: Row(
children: [
Text(
orderItem.quantity.toString() + 'x',
style: Title16,
),
SizedBox(
width: 8,
),
Flexible( //and here
child: Text(
orderItem.name, // no more overflow
style: Title18bold,
overflow: TextOverflow.ellipsis, //working as expected
),
),
],
),
),
As the documentation states, TextOverflow says how overflowing text should be handled, but it will not work if it's parent don't have a fixed size. In this case, Flexible is been used to restrict the total size of the text to prevent overflow, when it reaches a very large width.
I receive a list of images from api call, I need to layout these images like on this example, I have already implemented this logic, but I think it is redundant, and can be done easier, without hard-coded which item need to be first, last, etc.. and I think that widget tree could be less. How I can improve this code?
my emplementation:
List<Widget> _listImages() {
List<Widget> imagesList = [];
for (int i = 0; i < images.length; i++) {
imagesList.add(
Expanded(
child: Padding(
padding: const EdgeInsets.all(2.0),
child: GestureDetector(
onTap: () {
open(context);
},
child: child: NetworkImage(images[i]),
),
),
);
);
}
return imagesList;
}
Widget build(BuildContext context) {
return Card(...
Column(//Image layout
children: [
Row(
children: [
_listImages().first,
],
),
Container(
height: 110,
child: Row(
children: [
Expanded(
flex: 2,
child: Row(
children: _listImages().getRange(1, 3).toList(),
),
),
Expanded(
child: Stack(children: [
Row(
children: [
_listImages().elementAt(3),
],
),
IgnorePointer(
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
color: Colors.black54,
child: Center(
child: Text(
'+ ${_listImages().length - 3}',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.w500),
),
),
),
),
),
]),
),
],
),
),
],
)
....
}
You could try Gridview. You can use main axis spacing and cross axis spacing to change the distance between grid tiles.
https://www.geeksforgeeks.org/flutter-gridview/