【问题标题】:How to manually assign the first element of a Listview.builder in Flutter?如何在 Flutter 中手动分配 Listview.builder 的第一个元素?
【发布时间】:2020-12-07 10:48:36
【问题描述】:

我有一个 Flutter 应用程序,它在 Listview.builder 的卡片上显示事件(存储在 Cloud Firestore 中)。我有一个特定的事件,足球。它有自己的特殊卡片。列表中可以有多个常规赛事,但只有一项足球赛事。我想将此足球赛事显示在列表顶部,作为第一张卡片。我怎样才能做到这一点?

到目前为止我的代码:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fociapp/model/events.dart';
import 'package:fociapp/ui/event_card.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: Firestore.instance.collection("events").snapshots(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          return snapshot.hasData
              ? Container(
                  color: Colors.grey[850],
                  child: ListView.builder(
                    itemCount: snapshot.data.documents.length,
                    itemBuilder: (BuildContext context, int index) {
                      DocumentSnapshot events = snapshot.data.documents[index];
                      Event event = Event(
                          events["eventName"],
                          events["startTime"],
                          events["coverImageUrl"],
                          events["location"],
                          events["description"]);

                      return EventCard(event);
                    },
                  ),
                )
              : Center(
                  child: CircularProgressIndicator(),
                );
        });
  }
}

Event 是来自 Firestore 的数据的模型类,EventCard 是小部件,它将数据显示在卡片中。

【问题讨论】:

    标签: firebase flutter google-cloud-firestore android-listview stream-builder


    【解决方案1】:

    只能操作满足要求的数据,不能操作ListView。像这样:

    class HomePage extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return StreamBuilder(
                stream: Firestore.instance.collection("events").snapshots(),
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  return snapshot.hasData
                      ? Container(
                    color: Colors.grey[850],
                    child: createListView(snapshot.data.documents),
                  )
                      : Center(
                    child: CircularProgressIndicator(),
                  );
                });
          }
        
          Widget createListView(List<DocumentSnapshot> documentList){
            // find football and move it to the start position.
            DocumentSnapshot football = documentList.indexWhere((element) => element.eventName == 'football');
            documentList.remove(football);
            documentList.insert(0, football);
        
            return ListView.builder(
              itemCount: documentList.length,
              itemBuilder: (BuildContext context, int index) {
                DocumentSnapshot events = snapshot.data.documents[index];
                Event event = Event(
                    events["eventName"],
                    events["startTime"],
                    events["coverImageUrl"],
                    events["location"],
                    events["description"]);
        
                return EventCard(event);
              },
            );
          }
        }
    

    【讨论】:

      【解决方案2】:

      只需将 ItemCount 加一即可。 在您的 ItemBuilder 中,如果 index 为 0,则返回 Football-Card,如果不是,则返回您的普通卡(索引 - 1)。

      像这样:

      ListView.builder(
          itemCount: snapshot.data.documents.length + 1,
          itemBuilder: (BuildContext context, int index) {
             if(index == 0) {
                // return Football-Card
             } else {
                 DocumentSnapshot events = snapshot.data.documents[index - 1];
                 Event event = Event(
                     events["eventName"],
                     events["startTime"],
                     events["coverImageUrl"],
                     events["location"],
                     events["description"]);
      
                  return EventCard(event);
              }
           },
      ),
      

      【讨论】:

      • 你会错过一件物品
      • @Choy 不,您不会错过任何一项。我将 Listview 的 itemCount 增加了一个。
      【解决方案3】:

      在您的ListView.builder 中,您可以告诉它根据其index 显示其他内容。我们可以使用 if 语句来实现这一点。您的索引将始终从 0 开始,并且每次构建小部件后都会递增。您可以检查索引是否为 0,并在索引为 0 时显示您的足球赛事。

      ListView.builder(
                          itemCount: snapshot.data.documents.length,
                          itemBuilder: (BuildContext context, int index) {
                            if(index==0){
                            DocumentSnapshot events = snapshot.data.documents[index];
                            Event event = Event(
                                events["eventName"],
                                events["startTime"],
                                events["coverImageUrl"],
                                events["location"],
                                events["description"]);
      
                            return EventCard(event);
                            }
                            else{
                            //return your other things
                            }
                          },
                        ),
                      )
      

      【讨论】:

        猜你喜欢
        • 2020-05-12
        • 2021-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-27
        • 2021-10-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多