I am using an animatedContainer to reveal a listView.builder() when a button is pressed. It's a simple sublist to show, but the problem is the height of the ListView builder is not known by me to pass to animatedContainer height Constraint. Do there any way to get the height of the listview builder dynamically or any other method to achieve this?

What I need?

  • Animated container need height, but I don't know the height of listview builder.
  • While I was using Normal Container, i not set height: property, so it will wrap around the child automatically

Something like this: https://getbootstrap.com/docs/4.0/components/collapse/

AnimatedContainer(
duration: Duration(milliseconds: 200),
curve: Curves.easeIn,
height: _expanded ? 150 : 0, // This height I cannot set here explicitly. I need to set dynamically like, get child's height
child: ListView.builder(
  key: listViewKey,
  shrinkWrap: true,
  scrollDirection: Axis.vertical,
  physics: const NeverScrollableScrollPhysics(),
  itemCount: loadedSubCategories.length,
  itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
  value: loadedSubCategories[i],
  child: SubCategoryItem(loadedSubCategories[i].categoryId,
     loadedSubCategories[i].subCategoryId)),
  ),
),

While I am using a normal Container(), I wont set the height: property so that it will get the child's height automatically but I need the height because I would like to expanded the subcategories in a animated way.

Each element of SubCategories having different heights and the number of Subcategories is also Unknown. so calculating the height with subcategories.length is also not possible.

Any advice is really appreciated, Thank you


Solution 1: Balasubramani Sundaram

enter image description here

Using the Curves.fastLinearToSlowEaseIn and SizeBox.shrink to achieve your requirement

@override
Widget build(BuildContext context) {
  return SafeArea(
    bottom: true,
    top: false,
    child: Scaffold(
      appBar: AppBar(
        title: Text('Container'),
      ),
      body: Column(
        children: [
          Center(
            child: FlatButton(
                onPressed: () {
                  setState(() {
                    _expanded = true;
                  });
                },
                child: Text('expand')),
          ),
          AnimatedContainer(
            duration: Duration(seconds: 2),
            curve: Curves.fastLinearToSlowEaseIn,
            height: _expanded ? 150 : 0,
            clipBehavior: Clip.antiAlias,
            decoration: BoxDecoration(
                color: Colors.white
            ),
            child: _expanded ?  ListView.builder(
                shrinkWrap: true,
                scrollDirection: Axis.vertical,
                physics: const NeverScrollableScrollPhysics(),
                itemCount: 3,
                itemBuilder: (ctx, i) {
                  return ListTile(
                    title: Text(i.toString()),
                  );
                }) : SizedBox.shrink(),
          ),
        ],
      )
    ),
  );
}


Solution 2: R3HP

you can achieve what you're looking for with AnimatedSize widget .

it automatically creates a widget that animates itself to match it's child size and you don't need to provide any height or width to it. you just need to wrap your widget with it

AnimatedSize(
            curve: Curves.fastOutSlowIn,
            duration: Duration(milliseconds: 300),
            vsync: this,
            child: Container()
)

you can have look at for more information.