ListView.builder inside Stack returns Null Check error used on a null value

Viewed 17684

I'm trying to create a list of tasks inside a circle, when the user taps on it, the list is showed. The problem is that the list of tasks is dynamic, I need to use a ListView.builder but it keeps giving out errors. I've checked the following:

  • If instead of a .builder, I use a ListView, it works fine.
  • The itemCount and shrinkWrap have noting to do with it.

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox was not laid out: RenderViewport#1d072 NEEDS-PAINT 'package:flutter/src/rendering/box.dart': Failed assertion: line 1785 pos 12: 'hasSize' The relevant error-causing widget was ListView lib/TaskBubble.dart:43 ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════ Null check operator used on a null value ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by Flutter framework ═════════════════════════════════ Bad state: Future already completed ════════════════════════════════════════════════════════════════════════════════

And here is the code

class _TaskBubbleState extends State<TaskBubble> {
  double yOffset = 175.0;
  double xOffset = 50.0;

  bool hide = true;

  List<Task> tasks = [
    new Task(name: "Laundry", done: false),
    new Task(name: "hide", done: false)
  ];

  @override
  Widget build(BuildContext context) {
    return Positioned(
      top: yOffset,
      left: xOffset,
      child: Draggable<Widget>(
        onDraggableCanceled: (velocity, offset) {
          setState(() {
            yOffset = offset.dy;
            xOffset = offset.dx;
          });
        },
        feedback: FloatingActionButton(
          onPressed: () {},
        ),
        childWhenDragging: Opacity(
          opacity: 0.1,
          child: FloatingActionButton(
            onPressed: () {},
          ),
        ),
        child: Stack(
          children: [
            ListView.builder(
              itemCount: tasks.length,
              shrinkWrap: true ,
              itemBuilder: (context, index) => ListTile(
                title: Text(tasks[index].name),
              ),
            ),
            FloatingActionButton(
              onPressed: () {
                setState(() {
                  hide = !hide;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}
4 Answers

wrap your ListView.builder with Container provide a height to it.

like for your code-

child: Stack(
          children: [
            Container(
              height: 100.0,
              child: ListView.builder(
                itemCount: tasks.length,
                shrinkWrap: true ,
                itemBuilder: (context, index) => ListTile(
                  title: Text(tasks[index].name),
                ),
              ),
            ),
            FloatingActionButton(
              onPressed: () {
                setState(() {
                  hide = !hide;
                });
              },
            ),
          ],
        ),

I have this issue with ListView not necessarily with .builder. The solution was to add a scrollController. on your builder, add:

   ListView.builder(
          controller: _controller,//new line
          itemCount: tasks.length,
          shrinkWrap: true ,
          itemBuilder: (context, index) => ListTile(
            title: Text(tasks[index].name),
          ),

inistantiate your scroller:

ScrollController _controller;

initilize the controller:

@override
 void initState() {
 _controller = ScrollController();
 _controller.addListener(_scrollListener);//the listener for up and down. 
 super.initState();
}

add the listener.

_scrollListener() {
  if (_controller.offset >= _controller.position.maxScrollExtent &&
     !_controller.position.outOfRange) {
   setState(() {//you can do anything here
   });
 }
 if (_controller.offset <= _controller.position.minScrollExtent &&
    !_controller.position.outOfRange) {
   setState(() {//you can do anything here
    });
  }
}

while this solved the error: null check operator used on a null value the relevant error-causing widget was listview, and Bad state: Stream has already been listened to, I do not have streams or anything. I did not experience this in other ListView widgets. Not sure if this is with the new Flutter 1.22.2?? My case was only when getting values into a dropdown. Otherwise, same code works in another setting.

Add the key property in your ListTile(key: Key("Your Key"))

you can just wrap ListView with an Expanded widget

Stack(
  children: [
    Expanded(
        child: ListView.builder(
        itemCount: tasks.length,
        shrinkWrap: true ,
        itemBuilder: (context, index) => ListTile(
          title: Text(tasks[index].name),
        ),
      ),
    ),
)
Related