Home > Software design >  How to make Container height dynamic to fit ListView but to certain max height Flutter
How to make Container height dynamic to fit ListView but to certain max height Flutter

Time:07-09

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,
      ),
  • Related