仅在我第一次 运行 时出错 'The getter 'length' was called on null.接收者:空'

Error only in the first time I Run it 'The getter 'length' was called on null. Receiver: null'

所以我尝试构建 Sliverlist 在第一个 运行 我 hard-coding child 数到 20(例如)并且该应用程序运行正常 但是如果我尝试在第一个 运行 上将 childCount 设置为我的 FireStore 集合的长度,我会得到错误

======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building:
The getter 'length' was called on null.
Receiver: null
Tried calling: length

但是!如果我首先将 childCount 手动设置为 20,然后将 childCount 设置为 handlyCalls.length 对应用程序进行热重载,它会正常工作,有什么建议吗?

class HandlyCallsList extends StatefulWidget {
@override
_HandlyCallsListState createState() => _HandlyCallsListState();
}

class _HandlyCallsListState extends State<HandlyCallsList> {
@override
Widget build(BuildContext context) {

  final handlyCalls = Provider.of<List<HandlyCall>>(context);
  int count = 20;

return SliverList(
  delegate: SliverChildBuilderDelegate(
        (BuildContext context, index) {
          print('!!!!!!!!!!!! 11111111111111111111 ${handlyCalls.length}');
      return HandlyCallTile(handlyCall: handlyCalls[index]);
    },
    childCount: handlyCalls.length,
  ),
);

更新

这是 handyCall 列表功能

List<HandlyCall> _handlyCallListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((document) {
  return HandlyCall(
    title: document.data()['title'] ?? '',
    type: document.data()['type'] ?? '',
    reward: document.data()['reward'] ?? null,
    money: document.data()['money'] ?? 0,
    name: document.data()['name'] ?? '',
    rating: document.data()['rating'] ?? 25,
    user: document.data()['user'] ?? null,
  );
}).toList() ;
}

//get userProfile stream
Stream<List<HandlyCall>> get handlyCalls {
return handlyCallsCollection.snapshots().
map(_handlyCallListFromSnapshot);
}

我不确定 handlyCalls 是什么样的,但我认为对您来说最好的方法是在一个 class 中创建一个列表,它将在提供商中处理并包含一个 handlyCalls 列表和没有给提供者一个 handlyCalls 列表。

所以会像这样:

    class handlyCallsList extends ChangeNotifier {
    
      List<handlyCalls> _list;
    
      List<handlyCalls> get list => _list;
    
      void changeList(List<handlyCalls> list){
        this._list = list;
        notifyListeners(); // Important to notify all the listeners and make the listeners refresh the view
      }
    }

现在您应该使用默认值初始化您的提供程序,这样您就可以始终拥有一个列表,这样它就不会在第一个 运行.

中为空
ChangeNotifierProvider<handlyCallsList>(
      create: (_) => handlyCallsList()..changeList([]), // you can add the default list here for when it loads the first time so you will not find it null
);

您还可以检查该值以查看其返回的列表是否为空,或者使用 handlyCalls?.length 检查可能的空值。

好的,经过长时间的反复试验,我尝试了一种不同的方法,即使用 ListView 而不是 CustomScrollView,它就像魔术一样工作,我将 chiledCount 设置为我的 LIST.length 突然之间在那之后没有错误,我将代码更改为 ListView.Builder 并将 Home Scaffold 的主体更改为 NestedScrollView 并将我的 SliverAppBar 插入其中,可能是 SliverListDelegate

中的某些东西被破坏了

我的新密码:

      Scaffold(...
      body: NestedScrollView(
      floatHeaderSlivers: true,
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          SliverAppBar(...),
      ];
      },
      body: HandlyCallsList(),
    ),
  ),

列表视图生成器

class _HandlyCallsListState extends State<HandlyCallsList> {


@override
Widget build(BuildContext context) {


final handlyCalls = Provider.of<List<HandlyCall>>(context);

return ListView.builder(
  itemCount: handlyCalls.length,
    itemBuilder: (context, index) {
    return HandlyCallTile(handlyCall: handlyCalls[index],);
    }
);
}
}