0

I'm kind of new to Flutter so forgive my misunderstanding.

Ultimately, I'm trying to have a list of slivers each with a list of widgets (items) and that this list of slivers can change as well as each list of items can change.
Something like:

  • Sliver
    • Item
    • Item
      ...
  • Sliver
    • Item
      ...

etc, but I can keep adding and removing slivers and items at will. My naive approach is basically as follows:

  1. In my main widget build function create a CustomScrollView.
  2. Have this CustomScrollView reference a member variable list of slivers for its slivers argument.
  3. Add a button to create new slivers (add a sliver to the sliver list).
  4. Add a button to create new items (add an item to the item list).
  5. Call setState() when adding the item in (4).
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;
  final List<Widget> slivers = [];
  final List<Text> items = [];

  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  void _addSliver() {
    widget.slivers.add(SliverList(
      delegate: SliverChildBuilderDelegate(
              (context, index) {
                return index < widget.items.length ? widget.items[index] : null;
              })));
  }

  void _addToList() {
    setState(() {
      widget.items.add(Text('Item ${widget.items.length + 1}'));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.category),
            onPressed: _addSliver,
          ),
          IconButton(
            icon: Icon(Icons.add),
            onPressed: _addToList,
          )
        ],
      ),
      body: CustomScrollView(
        slivers: widget.slivers,
      ),
    );
  }
}

The code above is just to test a single sliver and multiple items in that sliver. I noticed while debugging that the already existing sliver is not being rebuilt in the _build function in sliver.dart because it already exists in the Map, so clearly my understanding of how this can be achieved is flawed.

Do I simply need to force it to rebuild somehow? Or is there a much easier way to do this that I am missing?

Itamar Bitton
  • 777
  • 2
  • 7
  • 25

1 Answers1

0

It seems the idea is different than using an array to hold the children of a Column for instance. The widgets need to be rebuilt every time build is called (besides the actual widgets being displayed apparently).

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;
  final Map<int, List<Text>> slivers = {};

  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  void _addSliver() {
    widget.slivers[widget.slivers.length] = [];
  }

  void _addToList(int listNumber) {
    setState(() {
      widget.slivers[listNumber].add(Text('Item ${widget.slivers[listNumber].length + 1}'));
    });
  }

  List<Widget> _buildSlivers() {
    List<Widget> slivers = [];
    widget.slivers.forEach((key, value) {
      slivers.add(SliverList(
        delegate: SliverChildBuilderDelegate(
                (context, index) => index < widget.slivers[key].length ?
                widget.slivers[key][index] : null)));
    });
    return slivers;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.category),
            onPressed: _addSliver,
          ),
          IconButton(
            icon: Icon(Icons.add),
            onPressed: () => _addToList(widget.slivers.length - 1),
          )
        ],
      ),
      body: CustomScrollView(
        slivers: _buildSlivers(),
      ),
    );
  }
}

If there's a better method for accomplishing this I'd really like to know.

Itamar Bitton
  • 777
  • 2
  • 7
  • 25