Alexandre Serra
Alexandre Serra

Reputation: 348

How to hide/minimize a ListView with an animation?

I want to have a button that when I click it, the listView disappears with an animation, like a "going up" animation. I managed to achieved this without animation with this code for the listview:

Visibility(
        // O valor aqui e o inicial
        visible: isExpanded,
        child: ListView.builder(
            scrollDirection: Axis.vertical,
            physics: NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            itemCount: 2,
            itemBuilder: (BuildContext context, int index) {
              return Column(
                children: <Widget>[
                  SizedBox(height: 30),
                  GameCard(locale: widget.locale)
                ],
              );
            }),
      )

And the button performs this action:

onTapHeader() {
    setState(() {
      if (isExpanded) {
        _controller.forward();
      } else {
        _controller.reverse();
      }
      isExpanded = !isExpanded;
    });
  }

Is there any way to animate this?

Upvotes: 3

Views: 3722

Answers (1)

Derek Fredrickson
Derek Fredrickson

Reputation: 752

There doesn't appear to be a native way to do this without abusing the ExpansionPanel widgets or doing your own thing. My solution was to use the expandable library since it's basically what you would have to do if you did your own thing.

Here's my code. It should be enough for you to tweak and do what you want.

import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    theme: ThemeData(accentColor: Colors.black87),
    home: ListExpansion(),
  ));
}

List<String> generateItems(int numberOfItems) {
  return List.generate(numberOfItems, (int index) {
    return 'Item $index';
  });
}

class ListExpansion extends StatefulWidget {
  @override
  _ListExpansionState createState() => _ListExpansionState();
}

class _ListExpansionState extends State<ListExpansion> {
  ExpandableController _controller;
  List<String> _data = generateItems(8);

  @override
  void initState() {
    super.initState();
    _controller = ExpandableController();
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("List Expansion"),
          actions: <Widget>[
            IconButton(
              tooltip: _controller.expanded ? "Collapse" : "Expand",
              icon: _controller.expanded ? Icon(Icons.expand_less) : Icon(Icons.expand_more),
              onPressed: () {
                setState(() {
                  _controller.toggle();
                });
              },
            ),
          ],
        ),
        body: ExpandablePanel(
          controller: _controller,
          hasIcon: false,
          tapHeaderToExpand: false,
          tapBodyToCollapse: false,
          collapsed: ListTile(
            title: Text("I am currently collapsed. Tap the button to expand me and see a list"),
          ),
          expanded: ListView.builder(
            itemCount: _data.length,
            itemBuilder: (BuildContext context, int index) {
              return ListTile(
                title: Text(_data[index]),
              );
            },
          ),
        ),
      ),
    );
  }
}

Make sure you add the pub dependency like so:

dependencies:
  flutter:
    sdk: flutter

  expandable: ^3.0.1

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

Sample of expanding a list

Upvotes: 4

Related Questions