仅在我第一次 运行 时出错 '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],);
}
);
}
}
所以我尝试构建 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],);
}
);
}
}