I am trying to show ListView in a custom dialog window. What I want to make dialog box height dynamic according to ListView content but to certain max height. If the ListView content reaches specific height it should me scrollable.
This is my code:
class PeekTableDialog extends StatefulWidget {
Order order;
PeekTableDialog({required this.order});
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return PeekTableDialogState();
}
}
class PeekTableDialogState extends State<PeekTableDialog> {
final ScrollController controller = ScrollController();
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
}
Widget getExtras(Food fooditem) {
List<String> extras = [];
for (var extra in fooditem.extras) {
if (fooditem.extras.last == extra) {
extras.add(extra.name);
} else {
extras.add(extra.name ', ');
}
}
return Wrap(
runSpacing: 2,
spacing: 2,
children: List.generate(
extras.length,
(index) {
return Text(
extras[index].toString(),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
),
);
},
),
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return SizedBox(
width: MediaQuery.of(context).size.width * 0.50,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
color: Colors.grey[400],
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
alignment: Alignment.center,
child: Row(
children: [
Expanded(
child: Container(
alignment: Alignment.center,
child: Text(
widget.order.table!.name,
style: AppTextStyles().style2,
),
),
),
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
padding: EdgeInsets.zero,
icon: Icon(
Icons.close,
color: Colors.white,
size: 35,
),
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
alignment: Alignment.center,
child: Text(
'\$' widget.order.total,
style: TextStyle(
color: Colors.grey[800],
fontSize: 35,
fontWeight: FontWeight.w400,
),
),
),
SizedBox(
height: 15,
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
child: Text(
'Qty',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
const SizedBox(
width: 10,
),
Expanded(
flex: 2,
child: Text(
'Item',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
child: Text(
'Price',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
child: Text(
'Disc.',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
),
],
),
const Divider(
color: Colors.grey,
height: 1.5,
),
const SizedBox(
height: 10,
),
Container(
padding: EdgeInsets.only(bottom: 30),
child: Scrollbar(
isAlwaysShown: true,
controller: controller,
thickness: 12,
showTrackOnHover: true,
child: ListView.separated(
itemCount: widget.order.cartItems.length,
controller: controller,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Container(
child: Row(
children: [
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: Text(
widget.order.cartItems[index].cartCount
.toString(),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
),
),
const SizedBox(
width: 10,
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
widget.order.cartItems[index].name,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
const SizedBox(
height: 5,
),
getExtras(widget.order.cartItems[index]),
],
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: Text(
'\$'
widget.order.cartItems[index].totalPrice
.toStringAsFixed(2),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: Text(
'\$'
widget
.order.cartItems[index].newDiscPrice
.toStringAsFixed(2),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
),
),
],
),
);
},
separatorBuilder: (context, index) {
return const SizedBox(height: 3);
},
),
),
),
],
),
),
],
),
);
}
}
Anyone help me please with this small issue. Thanks in advance.
CodePudding user response:
Well, It's pretty easy. All you have to do is to create a class like this :
class ExpandableText extends StatefulWidget {
ExpandableText(this.text, this.isLongText, {Key? key}) : super(key: key);
final String text;
bool isExpanded = false;
final bool isLongText;
@override
_ExpandableTextState createState() => _ExpandableTextState();
}
class _ExpandableTextState extends State<ExpandableText>
with TickerProviderStateMixin<ExpandableText> {
@override
void initState() {
if (widget.isLongText) {
setState(() {
widget.isExpanded = false;
});
} else {
widget.isExpanded = true;
}
super.initState();
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
AnimatedSize(
vsync: this,
duration: const Duration(milliseconds: 500),
child: ConstrainedBox(
constraints: widget.isExpanded
? const BoxConstraints(maxHeight: 250.0)
: const BoxConstraints(
maxHeight: 60.0,
),
child: SingleChildScrollView(
child: Text(
widget.text,
overflow: TextOverflow.fade,
),
),
),
),
widget.isExpanded
? ConstrainedBox(constraints: const BoxConstraints())
: TextButton(
style: const ButtonStyle(alignment: Alignment.topRight),
child: const Text(
'Expand..'
),
onPressed: () => setState(() => widget.isExpanded = true),
),
],
);
}
}
Just play with the maxHeight according to your needs. Call this class like this (inside your dialog window) :
ExpandableText(
dataToBeShown,
dataToBeShown.length > 250 ? true : false,
),