我正在尝试将两个不同的列表视图 Streambuilders 组合为一个屏幕
Posted
技术标签:
【中文标题】我正在尝试将两个不同的列表视图 Streambuilders 组合为一个屏幕【英文标题】:I am trying to combine two different list view, Streambuilders for a single screen 【发布时间】:2021-11-13 16:01:18 【问题描述】:我正在尝试连接两个不同的构建器以创建一个屏幕。我创建了两个小部件,一个可以水平滚动,另一个可以垂直滚动。我在将它们堆叠在一起以获得有凝聚力的屏幕时遇到问题。一开始它工作了一两次,然后我会收到一个错误
我不断收到此错误:
The following assertion was thrown building:
'package:flutter/src/painting/_network_image_io.dart':
Failed assertion:
line 25 pos 14: 'url != null': is not true.
When the exception was thrown, this was the stack
#2 new NetworkImage
package:flutter/…/painting/_network_image_io.dart:25
#3 songCard
package:CampFire/…/pages/browse.dart:146
#4 _BrowseState.songList
package:CampFire/…/pages/browse.dart:130
#5 _BrowseState.songsection.<anonymous closure>.<anonymous closure>
package:CampFire/…/pages/browse.dart:75
#6 SliverChildBuilderDelegate.build
package:flutter/…/widgets/sliver.dart:455...
代码:
class Browse extends StatefulWidget
@override
_BrowseState createState() => _BrowseState();
class _BrowseState extends State<Browse>
Future getdata() async
QuerySnapshot qn =
await FirebaseFirestore.instance.collection('songs').get();
return qn.docs;
List<DocumentSnapshot> _list;
@override
Widget build(BuildContext context)
return Scaffold(
appBar:
AppBar(
automaticallyImplyLeading: false,
title: Image.asset('assets/images/1.png', height: 95, width: 95),
centerTitle: true,
shape: Border(bottom: BorderSide(color: Colors.grey[50], width: 0.4)),
),
body: Stack(
children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 200,
child: videosection()
),
Container(
height: 1000,
child: songsection()
)
],
),
)
],
)
);
Widget songsection()
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('songs')
.orderBy('song_title')
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot)
if (!snapshot.hasData)
return Center(
child: CircularProgressIndicator(),
);
else
_list = snapshot.data.docs;
return ListView.custom(
shrinkWrap: true,
physics: ScrollPhysics(),
childrenDelegate: SliverChildBuilderDelegate(
(BuildContext context, int index)
return songList(context, _list[index]);
,
childCount: _list.length,
));
,
);
Widget videosection()
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('videos')
.orderBy('video_title')
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot)
if (!snapshot.hasData)
return Center(
child: CircularProgressIndicator(),
);
else
_list = snapshot.data.docs;
return ListView.custom(
shrinkWrap: true,
physics: ScrollPhysics(),
scrollDirection: Axis.horizontal,
childrenDelegate: SliverChildBuilderDelegate(
(BuildContext context, int index)
return videoList(context, _list[index]);
,
childCount: _list.length,
));
,
);
Widget songList(BuildContext context, DocumentSnapshot documentSnapshot)
return
InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Songspage(
song_title: documentSnapshot.data()["song_title"],
artist_name: documentSnapshot.data()["artist_name"],
song_url: documentSnapshot.data()["song_url"],
image_url: documentSnapshot.data()["image_url"],
))),
child: songCard(context, documentSnapshot)
);
Widget songCard(BuildContext context, DocumentSnapshot documentSnapshot)
return Column(
children: <Widget>[
SizedBox(height: 10,),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(width: 20,),
CircleAvatar(
backgroundImage: NetworkImage(documentSnapshot.data()["image_url"]),
backgroundColor: Colors.grey[50],
radius: 23,
),
SizedBox(width: 25,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text
(documentSnapshot.data()["song_title"],
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 18,
color: Colors.grey[50]
)
),
SizedBox(height: 5,),
Text
(documentSnapshot.data()["artist_name"],
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 13,
color: Colors.grey[50]
),
)
],
),
]
)
]
);
Widget videoList(BuildContext context, DocumentSnapshot documentSnapshot)
return
InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VideoPlayer(
video_title: documentSnapshot.data()["video_title"],
video_url: documentSnapshot.data()["video_url"],
Thumbnail: documentSnapshot.data()["Thumbnail"],
))),
child: videoCard(context, documentSnapshot)
);
Widget videoCard(BuildContext context, DocumentSnapshot documentSnapshot)
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
documentSnapshot.data()['Thumbnail'],
height: 90,
width: 220,
fit: BoxFit.cover,
),
),
SizedBox(height: 15,),
Text(
documentSnapshot.data()["video_title"],
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: Colors.grey[50]),
),
],
));
【问题讨论】:
【参考方案1】:您传递给NetworkImage
的参数documentSnapshot.data()["image_url"]
为空。如果文档中存在 image_url
字段及其值,请检查您的 Firestore 数据库。
NetworkImage(String url, double scale, Map<String, String> headers)
// The arguments [url] and [scale] must not be null.
Widget songCard(BuildContext context, DocumentSnapshot documentSnapshot)
print(documentSnapshot.data()["image_url"]);
// find out why it is null.
...
【讨论】:
以上是关于我正在尝试将两个不同的列表视图 Streambuilders 组合为一个屏幕的主要内容,如果未能解决你的问题,请参考以下文章
如何在 WPF / MVVM 中对绑定到相同实例的两个列表视图进行不同选择