Search code examples
flutterdartstream-builder

StackedIndex is causing a failed assertion error


I am attempting to create an application with a bottom navigation view. I changed the formatting of my StreamBuilder on one of the indexes, ever since I changed that streamBuilder I have been getting a weird error:

RenderBox was not laid out: RenderRepaintBoundary#eae01 relayoutBoundary=up2 NEEDS-PAINT 'package:flutter/src/rendering/box.dart': Failed assertion: line 1694 pos 12: 'hasSize'

Also I am getting:

Failed assertion: line 1697 pos 12: '!_debugDoingThisLayout': is not true.

Here are the build and the init I believe are causing the problem:

@override
  void initState() {
    super.initState();
    // TODO: implement initState
    _outerStream = Firestore.instance
        .collection('posts/player/post')
        .orderBy('time', descending: true)
        .snapshots()
        .take(2);

    _innerStream =
        Firestore.instance.collection('posts/player/post').snapshots();
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
      child: StreamBuilder<QuerySnapshot>(
        stream: _outerStream,
        builder: (context, snapshot) {
          if (!snapshot.hasData) return Container(child: Text('Loading...'));
          final int highLightCount = snapshot.data.documents.length;
          return StreamBuilder<QuerySnapshot>(
            stream: _innerStream,
            builder: (context, snapshot) {
              if (!snapshot.hasData)
                return Container(child: Text('There are no current posts'));
              return ListView(
                physics: const AlwaysScrollableScrollPhysics(),
                scrollDirection: Axis.vertical,
                shrinkWrap: true,
                children: getPostItems(snapshot),
              );
            },
          );
        },
      ),
    );
  }

this code is definitely messy right now, but here are the additional methods being used:

getPostItems(AsyncSnapshot<QuerySnapshot> snapshot) {
    return snapshot.data.documents.map((doc) => getListItem(doc)).toList();
  }

  Widget getListItem(var doc) {
    getProfUrl(doc);
    getDownUrl(doc);

    VideoPlayerController _videoPlayerController;
    _videoPlayerController = VideoPlayerController.network(downUrl)
      ..initialize();
    _videoPlayerController.setLooping(true);
    _videoPlayerController.play();

    if (doc["user"] != widget.auth.getUserId()) {
      print("will show");
      if (doc["type"] == "image") {
        return new Column(
          children: <Widget>[
            new GestureDetector(
              onTap: () {
                Navigator.push(
                  context,
                  new MaterialPageRoute(
                      builder: (context) => new playerViewProfilePageIndex(
                          widget.auth, doc["user"])),
                );
              },
              child: new ListTile(
                title: new Text(doc["title"]),
                subtitle: new Text(doc["description"].toString()),
                leading: new Container(
                  width: 44.0,
                  height: 44.0,
                  decoration: new BoxDecoration(
                    shape: BoxShape.circle,
                    image: new DecorationImage(
                        fit: BoxFit.fill, image: NetworkImage(profUrl)),
                  ),
                ),
              ),
            ),
            new Padding(
              padding: EdgeInsets.fromLTRB(4, 4, 4, 4),
              child: new Center(
                child: new AspectRatio(
                  aspectRatio: 1 / 1,
                  child: new Container(
                    decoration: new BoxDecoration(
                        image: new DecorationImage(
                      fit: BoxFit.fill,
                      alignment: FractionalOffset.topCenter,
                      image: new NetworkImage(downUrl),
                    )),
                  ),
                ),
              ),
            ),
          ],
        );
      } else {
        return new Column(children: <Widget>[
          new ListTile(
              title: new Text(doc["title"]),
              subtitle: new Text(doc["description"].toString()),
              leading: new Container(
                  width: 44.0,
                  height: 44.0,
                  decoration: new BoxDecoration(
                    shape: BoxShape.circle,
                    image: new DecorationImage(
                        fit: BoxFit.fill, image: NetworkImage(profUrl)),
                  ))),
          new Padding(
            padding: EdgeInsets.fromLTRB(4, 4, 4, 4),
            child: new Center(
              child: new AspectRatio(
                aspectRatio: 500 / 500,
                child: VideoPlayer(_videoPlayerController),
              ),
            ),
          ),
        ]);
      }
    }
  }

Solution

  • getListItem is expecting to return a Widget but when doc["user"] != widget.auth.getUserId() is false it never returns a value, maybe adding a dummy SizedBox.shrink with an else could help

    Widget getListItem(var doc) {
        getProfUrl(doc);
        getDownUrl(doc);
    
        VideoPlayerController _videoPlayerController;
        _videoPlayerController = VideoPlayerController.network(downUrl)
          ..initialize();
        _videoPlayerController.setLooping(true);
        _videoPlayerController.play();
    
        if (doc["user"] != widget.auth.getUserId()) {
          print("will show");
          if (doc["type"] == "image") {
            return new Column(
              children: <Widget>[
                new GestureDetector(
                  onTap: () {
                    Navigator.push(
                      context,
                      new MaterialPageRoute(
                          builder: (context) => new playerViewProfilePageIndex(
                              widget.auth, doc["user"])),
                    );
                  },
                  child: new ListTile(
                    title: new Text(doc["title"]),
                    subtitle: new Text(doc["description"].toString()),
                    leading: new Container(
                      width: 44.0,
                      height: 44.0,
                      decoration: new BoxDecoration(
                        shape: BoxShape.circle,
                        image: new DecorationImage(
                            fit: BoxFit.fill, image: NetworkImage(profUrl)),
                      ),
                    ),
                  ),
                ),
                new Padding(
                  padding: EdgeInsets.fromLTRB(4, 4, 4, 4),
                  child: new Center(
                    child: new AspectRatio(
                      aspectRatio: 1 / 1,
                      child: new Container(
                        decoration: new BoxDecoration(
                            image: new DecorationImage(
                          fit: BoxFit.fill,
                          alignment: FractionalOffset.topCenter,
                          image: new NetworkImage(downUrl),
                        )),
                      ),
                    ),
                  ),
                ),
              ],
            );
          } else {
            return new Column(children: <Widget>[
              new ListTile(
                  title: new Text(doc["title"]),
                  subtitle: new Text(doc["description"].toString()),
                  leading: new Container(
                      width: 44.0,
                      height: 44.0,
                      decoration: new BoxDecoration(
                        shape: BoxShape.circle,
                        image: new DecorationImage(
                            fit: BoxFit.fill, image: NetworkImage(profUrl)),
                      ))),
              new Padding(
                padding: EdgeInsets.fromLTRB(4, 4, 4, 4),
                child: new Center(
                  child: new AspectRatio(
                    aspectRatio: 500 / 500,
                    child: VideoPlayer(_videoPlayerController),
                  ),
                ),
              ),
            ]);
          }
        } else return const SizedBox.shrink(); //return a Widget when the if is false
      }