Why does this row don't wrap in flutter - flutter

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
],
),
);
}
}

Related

Flutter Flex Widget

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)),
],
),
)
],
),
),

Widget is taking maximum space in Flutter

I have some widgets (message bubbles ) inside a StreamBuilder, however this message bubbles are taking the maximum space possible when they should adapt to the size of the text inside.
This is the code of the main screen:
#override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('messages').snapshots(),
builder: (context, snapshot){
List<Widget> messagesWidgets = [];
if (snapshot.hasData){
final messages = snapshot.data.docs;
for (var message in messages){
final messageText = message.data()['text'];
final messageSender = message.data()['sender'];
final messageWidget = MessageBubble(
text: messageText,
sender: messageSender,
);
messagesWidgets.add(messageWidget);
}
}
return Expanded(
child: ListView(
//padding: EdgeInsets.symmetric(horizontal: 0.0, vertical: 20.0),
children: messagesWidgets,
),
);
},
),
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 6,
child: TextInput(
textAlign: TextAlign.left,
onChanged: (value){
messageText = value;
},
hintText: 'Type a message',
),
),
Expanded(
flex: 1,
child: Button(
child: Icon(Icons.send, color: background,),
function: (){
if(messageText.trim() == '') return;
_firestore.collection('messages').add({
'text': messageText,
'sender': Usr.email,
});
setState(() {
messageText = '';
});
},
tag: 'hey2d2',
),
),
],
),
),
],
),
);
And this is the code of the message bubbles:
#override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
child: Material(
elevation: 10.0,
borderRadius: BorderRadius.circular(30.0),
color: Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'$sender',
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: background,
),
),
Text(
'$text',
style: TextStyle(
fontSize: 15.0,
color: background,
),
),
],
),
),
),
),
);
Here there is a screenshot of what I mean:
This happens because the ListView widget automatically forces its children to take up all the available width. You can bypass this behaviour by wrapping the message bubble container with the Align widget. See below:
#override
Widget build(BuildContext context) {
return Align(
// Set the align's alignment to centerLeft.
alignment: Alignment.centerLeft,
child: Container(
...
),
);
}

How can I align texts?

I'm trying to create a leaderBoard. But I can't get the texts in the same alignment. How can I put the texts in the same line? As I understand it, I cannot put the texts in line because I use mainAxisAlignment: MainAxisAlignment.spaceBetween in the row section. Is there any other way to line up the texts?
return Container(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Sıralama",style: TextStyle(fontSize: 20), ),
Text("İsim Soyisim",style: TextStyle(fontSize: 20) ),
Text("Doğru cevap",style: TextStyle(fontSize: 20) ),
],
),
Divider(thickness: 2,color: Colors.grey,),
Expanded(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (index == 0)
Container(
width: 50,
height: 50,
child: Image.asset(
"assets/images/gold.png"))
else if (index == 1)
Container(
color: Colors.red,
width: 50,
height: 50,
child: Image.asset(
"assets/images/silver.png"))
else if (index == 2)
Container(
width: 50,
height: 50,
child: Image.asset(
"assets/images/bronze.png"))
else if (index > 2)
Text('${index + 1}',
style: TextStyle(fontSize: 20)),
Align(
child: Text(
'${snapshot.data[index].name}',
style: TextStyle(fontSize: 20)),
alignment: Alignment.centerLeft,),
Text(
'${snapshot.data[index].dogruCevap.toString()}',
style: TextStyle(fontSize: 20))
],
),
);
}),
),
],
));
You can use the DataTable for better UI and easy to render the table.
List<String> images = [
"assets/images/gold.png",
"assets/images/silver.png",
"assets/images/bronze.png"
];
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('DataTable'),
),
body: Container(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
DataColumn(
label: Text("Sıralama", style: TextStyle(fontSize: 20))),
DataColumn(
label:
Text("İsim Soyisim", style: TextStyle(fontSize: 20))),
DataColumn(
label: Text("Doğru cevap", style: TextStyle(fontSize: 20))),
],
rows: snapshot.data.asMap().entries.map<DataRow>((e) {
return DataRow(cells: [
DataCell(Image.asset(images[e.key])),
DataCell(Text(
'${e.value.name}',
style: TextStyle(fontSize: 20))),
DataCell(Text(
'${e.value.dogruCevap.toString()}',
style: TextStyle(fontSize: 20))),
]);
}).toList(),
),
),
),
),
);
}
Using a Table will simplify your widget:
import 'package:flutter/material.dart';
class Score {
final String name;
final int score;
Score(this.name, this.score);
static Widget getSymbol(int position) {
switch (position) {
case 0:
return Icon(Icons.directions_boat);
case 1:
return Icon(Icons.directions_train);
case 2:
return Icon(Icons.directions_bike);
default:
return Text((position + 1).toString(),
style: TextStyle(fontSize: 24.0));
}
}
}
List<Score> scores = [
Score('Azerty', 3),
Score('Qwertyuiop', 9),
Score('Wxcvbn', 0),
Score('Qsd', 7),
];
void main() {
runApp(
MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
columnWidths: {
0: FlexColumnWidth(2),
1: FlexColumnWidth(3),
2: FlexColumnWidth(3),
},
children: [
TableRow(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 2.0)),
),
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Sıralama"),
),
Text("İsim Soyisim"),
Text("Doğru cevap"),
],
),
...scores
.asMap()
.entries
.map(
(entry) => TableRow(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.centerLeft,
child: Score.getSymbol(entry.key),
),
),
Text(
'${entry.value.name}',
),
Text(
'${entry.value.score.toString()}',
),
],
),
)
.toList(),
],
),
),
),
);
}

How to make image layout inside card like this?

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/

Flutter invalid refrence to 'this' expression

i am trying to add item in list when i click on add button, all code is ok, but i am getting error invalid reference to this expression. i am using stateful widget.
List<Widget> _listSection = [];
body: Container(
child: Stack(
children: [
FloatingActionButton(
onPressed: () {
_listSection.add(
listSectionMethod(
"title three", "hello from click", Icons.forward),
);
setState(() {});
},
),
],
),
),
),
);
}
}
Widget listSection = Container(
margin: EdgeInsets.only(top: 210),
child: ListView(
children: [
Column(
children: [
Column(
children: this._listSection, // ----> ERROR HERE
),
],
),
],
),
);
List Section Method:
Card listSectionMethod(String title, String subtitle, IconData icon) {
return new Card(
child: ListTile(
title: Text(
title,
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(subtitle),
trailing: Icon(
icon,
color: Colors.blue,
),
),
);
}
change this:
Widget listSection = Container(
margin: EdgeInsets.only(top: 210),
child: ListView(
children: [
Column(
children: [
Column(
children: this._listSection,
),
],
),
],
),
);
for this:
Widget listSection() {
return Container(
margin: EdgeInsets.only(top: 210),
child: ListView(
children: [
Column(
children: this._listSection,
),
],
),
);
}