Как добавить новые элементы ListView вверху

Я получаю ListView.builder() элементов из Cloud Firestore внутри StreamBuilder. Я хочу, чтобы новый элемент был добавлен вверху ListView. Как я могу это сделать? Я попробовал reverse : true , хотя он переворачивает ListView, но когда есть только 2/3 элементов, ListView выглядит некрасиво, так как ListView начинается снизу, а верхняя часть экрана остается пустой.


person Newaj    schedule 03.08.2019    source источник
comment
Посмотрите, поможет ли это   -  person Sukhi    schedule 03.08.2019
comment
@Sukhi Мои данные поступают из firestore. Не могу установить индекс вручную.   -  person Newaj    schedule 03.08.2019
comment
вы можете просто добавить orderBy в запрос firebase?   -  person Aaron Saunders    schedule 05.08.2019


Ответы (4)


Добавил shrinkWrap: true и поместил ListView в виджет Align с alignment: Alignment.topCenter и получил желаемый результат!

              Align(
                alignment: Alignment.topCenter,
                child: ListView.builder(
                  reverse: true,
                  shrinkWrap: true,
                  ...
                  ...
               )
             )
person Newaj    schedule 04.08.2019

  • если вы хотите добавить новый элемент вверху списка, и если вы используете firestore, используйте Timestamp

база огня. пожарный магазин. Отметка времени

Отметка времени представляет собой момент времени, не зависящий от часового пояса.

используйте этот метод

Временная метка.сейчас()

получить данные из firestore по времени с помощью StreamBuilder

  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);

}

person amir khan    schedule 22.02.2020
comment
Это способ добавить данные в FirestoreDb, а затем отобразить, а не просто добавить в список (например, рекламу)... - person Alex Efimov; 13.12.2020

Имейте в виду, что первыми в вашем списке, т. е. вверху, являются элементы, которые находятся на первых позициях вашего массива. Если это так, вы можете инвертировать массив.

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.
    );
  }
}
person Claudio Castro    schedule 03.08.2019
comment
Проблема в том, что мои данные поступают из firestore и внутри StreamBuilder, не знаю, как их отменить. Получение данных в виде DocumentSnapshot внутри элемента управления ListView. - person Newaj; 04.08.2019

Просто создайте переменную с обратным индексом длины снимков, вот пример:

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]);
            });
      }),
person Erick Llerenas    schedule 11.09.2020