如何在顶部附加新的 ListView 项

How to append new ListView items at the top

我正在 StreamBuilder 中从 Cloud Firestore 中获取 ListView.builder() 项。我希望将新项目添加到 ListView 的顶部。我怎样才能做到这一点?我尝试了 reverse : true ,虽然它反转了 ListView,但是当只有 2/3 项时,ListView 看起来很难看,因为 ListView 从底部和顶部开始屏幕的一部分仍然是空的。

请记住,在您的列表中排在首位的是位于数组首位的项目。如果是这样,你可以反转数组。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);


  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  List<int> Items = [5, 4, 3, 2, 1];

  void _incrementItems() {
    setState(() {
      Items = List.from([9, 8, 7, 6])..addAll(Items);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: ListView.builder(
      itemCount: Items.length,
      itemBuilder: (context, index) {
          return  Text(
"Item "+Items[index].toString());

      },
    ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementItems,
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

添加了 shrinkWrap: true 并将 ListView 放入带有 alignment: Alignment.topCenterAlign 小部件中,得到了我想要的结果!

              Align(
                alignment: Alignment.topCenter,
                child: ListView.builder(
                  reverse: true,
                  shrinkWrap: true,
                  ...
                  ...
               )
             )
  • 如果你想在列表视图的顶部添加新项目并且如果你是 使用 firestore 使用 Timestamp

火力基地。火炉。时间戳

时间戳表示独立于任何时区的时间点

使用这个方法

Timestamp.now()

使用 StreamBuilder 按时间从 firestore 顺序获取数据

  Widget item() =>
  StreamBuilder<QuerySnapshot>(
    //fetch data from friends collection order by time
    stream: Firestore.instance.collection("friends").orderBy(
        "time", descending: true).snapshots(),
    builder: (context, snapshot) {
      //if data not exist show loading indicator
      if (!snapshot.hasData)
        return CircularProgressIndicator();
      //if data exist 
      return ListView.builder(itemBuilder: (context, index) {
        return Text(snapshot.data.documents[index].data['name']);
      });
    },
  );

在 firestore 中添加数据

 Firestore.collection("friends")
      .document(friends.otherUID)
      .setData({"name" : "xyz","time": Timestamp.now()});
  • 如果您想更新项目并且想在列表视图的顶部添加更新的项目

更新数据

     Future<void> updatefriends({String name,Timestamp time}) async {
Map<String, Object> updateFriend = Map();

if (name.isNotEmpty) updateFriend['name'] = name;
if (time !=null) updateFriend['time']=time;


Firestore.instance.collection("friends")
    .document(uid)
    .updateData(updateFriend);

}

StoreConnector<_ViewModel, List<Message>>(
      converter: (store) {
        // check mark ,reverse data list
        if (isReverse) return store.state.dialogList;
        return store.state.dialogList.reversed.toList();
      },
      builder: (context, dialogs) {
        // Add a callback when UI render after. then change it direction;
        WidgetsBinding.instance.addPostFrameCallback((t) {
          // check it's items could be scroll
          bool newMark = _listViewController.position.maxScrollExtent > 0;
          if (isReverse != newMark) { // need 
            isReverse = newMark;  // rebuild listview
            setState(() {});
          }
        });

        return ListView.builder(
          reverse: isReverse, // if it has less data, it will false now;
          controller: _listViewController,
          itemBuilder: (context, index) => _bubbleItem(context, dialogs[index], index),
          itemCount: dialogs.length,
        );
      },
    )

只需创建一个具有快照长度的反向索引的变量,这是一个示例:

StreamBuilder(
      stream: Firestore.instance.collection('news').snapshots(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (!snapshot.hasData) return Text('Loading...');
        int reverseIndex = snapshot.data.documents.length;
        return ListView.builder(
            itemCount: snapshot.data.documents.length,
            itemBuilder: (context, index) {
              reverseIndex -=1;
              return _buildItems(context, snapshot.data.documents[reverseIndex]);
            });
      }),