我正在尝试将两个不同的列表视图 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 组合为一个屏幕的主要内容,如果未能解决你的问题,请参考以下文章

同一列表的多个不同视图[重复]

jQuery 移动列表视图和面板

如何在 WPF / MVVM 中对绑定到相同实例的两个列表视图进行不同选择

将两个 SQL 列加载到列表视图中但只需要显示第一列 Android

正在检查视图模型的长度

在自定义适配器的列表视图项中加载不同的图像