flutterflutter-layoutstaggered-gridview

Null check operator used on a null value - StaggeredGridView


I'm working on a 'Notes' app.

So far, it has a HomeScreen() and Note() widget. The first is the screen where the notes are to be displayed and the second is a custom widget which is inflated by the way the notes are going to be displayed. I'm using Card() to display each note.

To dynamically set the sizes of the Cards, I'm using StaggeredGridView.

Here's my code.. notesList is the array of notes.

import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:get_it/get_it.dart';

import '../models/notes_list.dart';
import '../services/notes_service.dart';
import '../note.dart';
import './add_note_screen.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  NotesService get service => GetIt.I<NotesService>();
  List<NotesList> notesList = [];

  @override
  void initState() {
    notesList = service.getNotes();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: notesList.length == 0
          ? AppBar(title: Text('Create a Note'))
          : AppBar(title: Text('Safe')),
      body: StaggeredGridView.builder(
        padding: EdgeInsets.all(10),
        itemCount: notesList.length,
        gridDelegate: SliverStaggeredGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          staggeredTileBuilder: (index) => StaggeredTile.fit(1),
        ),
        itemBuilder: (_, index) => Note(
          notesList[index].noteTitle,
          notesList[index].noteContent,
          notesList[index].noteDateTime,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => Navigator.push(
            context, MaterialPageRoute(builder: (_) => AddNoteScreen())),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
    );
  }
}

I want to display only 2 notes across the screen and with the help of above code, I'm able to achieve that.

One problem I was already facing was that the StaggeredGridView was scrolling infinitely. My actual work today was to solve this issue. However, I stumbled upon a new issue and that's

Null check operator used on a null value

My debug console points to the StaggeredGridView as the source of this error. I'm trying to find a solution, only I couldn't.

Here's the error stack trace.

The following assertion was thrown during performLayout():
'package:flutter_staggered_grid_view/src/rendering/sliver_variable_size_box_adaptor.dart': Failed assertion: line 365 pos 12: 'child != null': is not true.

The relevant error-causing widget was
SliverStaggeredGrid
..\…\widgets\staggered_grid_view.dart:506
When the exception was thrown, this was the stack
#2      RenderSliverVariableSizeBoxAdaptor.paintExtentOf
package:flutter_staggered_grid_view/…/rendering/sliver_variable_size_box_adaptor.dart:365
#3      RenderSliverStaggeredGrid.performLayout
package:flutter_staggered_grid_view/…/rendering/sliver_staggered_grid.dart:317
#4      RenderObject.layout
package:flutter/…/rendering/object.dart:1777
#5      RenderSliverEdgeInsetsPadding.performLayout
package:flutter/…/rendering/sliver_padding.dart:132
#6      RenderSliverPadding.performLayout
package:flutter/…/rendering/sliver_padding.dart:371

Solution

  • I've discovered StaggeredGridView.builder throws that error when it's not enough items to cover the screen, if you use shrinkWrap: true you'll have to provide bounded height, which is not a universal solution,

    but according to your expectations, StaggeredGridView.countBuilder is more appropriate to use in your situation.

    So, I've used StaggeredGridView.countBuilder, it requires all necessary parameters and it works for me with your HomeScreen code:

    StaggeredGridView.countBuilder(
        padding: EdgeInsets.all(10),
        itemCount: notesList.length,
        crossAxisCount: 2,
        staggeredTileBuilder: (index) => StaggeredTile.fit(1),
        itemBuilder: (_, index) => Note(
          notesList[index].noteTitle,
          notesList[index].noteContent,
          notesList[index].noteDateTime,
        ),
      )