How can I make the text widget’s height increase base on its content?
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ตลาดหลักทรัพย์',
theme: ThemeData(primarySwatch: Colors.indigo),
home: const MyHomePage(title: 'ตลาดหลักทรัพย์'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<MaterialData> data = [
MaterialData('ไม้กระดาน', 48, 0),
MaterialData('วิญญาณร้าย', 39, 1),
MaterialData('ตุ๊กตาหิมะ', 31, 0),
MaterialData('ทองคำ', 609000000000, 1),
MaterialData('ไข่เอเลียน', 31, 0),
MaterialData('ทับทิม', 582, -18),
MaterialData('ล็อบสเตอร์ทอง', 2500, 0),
MaterialData('เหล็ก', 43000, 5000),
MaterialData('น้ำมันกลั่น', 43, 0),
MaterialData('ไก่ในถาด', 34, 1),
];
List<MaterialData> a = List<MaterialData>.empty();
@override
void initState() {
a = List<MaterialData>.generate(10000, (i) => data[i % 10]);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:
ListView.builder(
itemCount: a.length,
prototypeItem: MaterialPriceListItem(
label: a.first.label,
price: a.first.price,
priceDiff: a.first.priceDiff,
),
itemBuilder: (context, index) {
return MaterialPriceListItem(
label: a[index].label,
price: a[index].price,
priceDiff: a[index].priceDiff,
);
},
),
);
}
}
class MaterialPriceListItem extends StatelessWidget {
final String label;
final double price;
final double priceDiff;
const MaterialPriceListItem({
Key? key,
required this.label,
required this.price,
required this.priceDiff,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.fromLTRB(8, 13.0, 8, 13.0),
child: Row(
children: [
getIcon(priceDiff),
Expanded(
flex: 7,
child: Container(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
alignment: Alignment.centerLeft,
child: Text(
label,
style: const TextStyle(
fontSize: 22,
),
),
),
),
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
alignment: Alignment.center,
child: Text(
"${moneyFormat(price)} $",
style: TextStyle(
color: getColor(priceDiff),
fontSize: 18,
),
),
),
),
Expanded(
flex: 1,
child: Container(
padding: const EdgeInsets.fromLTRB(8.0, 0, 0, 0),
alignment: Alignment.center,
child: Text(
getPriceChangeText(priceDiff),
style: TextStyle(
color: getColor(priceDiff),
fontSize: 14,
),
),
),
),
],
),
);
}
String moneyFormat(double value) {
var nf = NumberFormat("##,###.##", "en_US");
return nf.format(value);
}
String getPriceChangeText(double priceChange) {
if (priceChange.sign > 0) {
return "+${moneyFormat(priceChange.abs())}";
} else if (priceChange.sign < 0) {
return "-${moneyFormat(priceChange.abs())}";
} else {
return moneyFormat(priceChange);
}
}
Widget getIcon(double priceChange) {
if (priceChange < 0) {
return FaIcon(
FontAwesomeIcons.arrowDown,
color: getColor(priceChange),
size: 18,
);
} else if (priceChange > 0) {
return FaIcon(
FontAwesomeIcons.arrowUp,
color: getColor(priceChange),
size: 18,
);
} else {
return Center(
child: FaIcon(
FontAwesomeIcons.arrowRight,
color: getColor(priceChange),
size: 18,
),
);
}
}
Color getColor(double priceChange) {
if (priceChange < 0) {
return const Color.fromARGB(255, 198, 40, 40);
} else if (priceChange > 0) {
return const Color.fromARGB(255, 46, 125, 50);
} else {
return const Color.fromARGB(255, 21, 101, 192);
}
}
}
3
Answers
Removing
protoTypeItem
solved the issue. even this is more efficient forListView
but it's not suitable for the list item that has vary height.Wrap your text widgets to Expanded and then add maxlines properties of Text widget to 2 or 3. For example,
Wrap your text widgets to "Wrap" for example: