1

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

MBK
  • 2,589
  • 21
  • 25
  • Wrap ur `ListView.builder` with normal `Container` and give stabile height value – theiskaa Feb 08 '21 at 12:57
  • Okay, i got what you want. Create Animation and animationcontroller after creating this you need to create initState method and here make implementation of your animationController, then implement ur Animation and give parameter of Tween – theiskaa Feb 08 '21 at 13:00
  • So you should create your custom animation container – theiskaa Feb 08 '21 at 13:01
  • so with that way, i dont want to set the height ? do the container understand the child height and expand with animation? – MBK Feb 08 '21 at 13:03
  • _heightAnimation = Tween( begin: Size(double.infinity, 100), end: Size(double.infinity, 350)) .animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn)); What height should I set? as i mentioned I cannot set the height manually. Do any way to get the child height. – MBK Feb 08 '21 at 13:04
  • No you was creating a new widget it would be custom animation container so you can give values in to Tween its takes two variables - begin and end, you can give double values whatever you want – theiskaa Feb 08 '21 at 13:04
  • And use this like : `_heightAnimation.value` – theiskaa Feb 08 '21 at 13:06
  • i don't know how to get the width of the child while running. – MBK Feb 09 '21 at 16:18

3 Answers3

16

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.

R3HP
  • 470
  • 4
  • 13
0

Instead of using AnimatedContainer you can use AnimatedCrossFade

Like this

AnimatedCrossFade(
duration: Duration(milliseconds: 200),
curve: Curves.easeIn,
  crossFadeState: _expanded ? CrossFadeState.showFirst : CrossFadeState.showSecond,
                                          
firstChild: 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)),
  ),
 secondChild: Container(),
),

This works for me.

-1

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(),
          ),
        ],
      )
    ),
  );
}
  • 3
    Bro, I got the animation working correctly before itself. but the height 150 cannot be set explicity. Do there any way to get rid of `height: _expanded ? 150 : 0,`. Like in normal container the height will automatically got from its child ***if we not set height property*** – MBK Feb 08 '21 at 13:55