1

我的应用程序主页上有一个 FutureBuilder,它在未来完成后返回一个 SliverFixedExtentList。它看起来像这样:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:project_spruce/DataBase/DataBaseConnection.dart';
import 'package:project_spruce/states/UserState.dart';
import 'package:project_spruce/widgets/FabBottomAppBar.dart';
import 'package:project_spruce/widgets/FoodItemCard.dart';
import 'package:provider/provider.dart';

class HomeScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    final List<DocumentSnapshot> _documents = List<DocumentSnapshot>();
    String uid = Provider.of<UserState>(context).firebaseUser.uid;
    return FutureBuilder(
      future: Provider.of<DataBaseConnection>(context).getQuerySnapshot('eatenFoods/'+ uid +'/food'),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
        Widget child;
        if (snapshot.hasData){
          _documents.clear();
          snapshot.data.documents.forEach((doc)=> _documents.add(doc));
          child = SliverFixedExtentList(
            itemExtent: 150,
            delegate: new SliverChildBuilderDelegate(
              (context, index) => FoodItemCard(_documents[index]),
              childCount: _documents.length,
            ),
          );
        }else {
          child = SliverToBoxAdapter(child: CircularProgressIndicator());
        }
        return Scaffold(
            floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
            floatingActionButton: FloatingActionButton(
              onPressed: () => Navigator.pushNamed(context, '/camera_screen'),
              tooltip: 'Add',
              elevation: 2,
              child: Icon(Icons.add),
              backgroundColor: Theme.of(context).primaryColor,
              foregroundColor: Colors.white,
            ),
            bottomNavigationBar: FabBottomAppBar(
              backgroundColor: Theme.of(context).primaryColor,
              color: Colors.white,
              selectedColor: Colors.white,
              iconSize: 30,
              notchedShape: CircularNotchedRectangle(),
              items: [
                FabBottomAppBarItem(iconData: Icons.search, text: 'Search'),
                FabBottomAppBarItem(iconData: Icons.pie_chart, text: 'Statistics'),
                FabBottomAppBarItem(
                    iconData: Icons.storage, text: 'Food Inventory'),
                FabBottomAppBarItem(iconData: Icons.person, text: 'Profile'),
              ],
              onTabSelected: (int tabIndex) {
                switch (tabIndex) {
                  case 0:
                    {
                      // Search
                      Navigator.pushNamed(context, '/search');
                    }
                    break;
                  case 1:
                    {
                      // Statistics
                      Navigator.pushNamed(context, '/stats');
                    }
                    break;
                  case 2:
                    {
                      // Inventory
                      Navigator.pushNamed(context, '/inventory');
                    }
                    break;
                  case 3:
                    {
                      // Profile
                      Navigator.pushNamed(context, '/profile');
                    }
                    break;
                }
              },
            ),
            body: new CustomScrollView(
              slivers: <Widget>[
                SliverAppBar(
                  //title: const Text('Home Page'),
                  actions: <Widget>[
                    IconButton(
                      icon: const Icon(Icons.notifications),
                      tooltip: 'Notifications',
                      onPressed: () => (){}, //(Navigator.pushNamed(context, '/notifications')),
                    ),
                  ],
                  floating: true,
                  pinned: true,
                  snap: false,
                  forceElevated: true,
                  expandedHeight: 200.0,
                  flexibleSpace: FlexibleSpaceBar(
                    title:
                        Text("Hi, " + Provider.of<UserState>(context).user.name),
                  centerTitle: false,
                  ),
                ),
                child,
              ],
            )
            );
      }
    );
  }
}

Future 从数据库中获取文档列表,然后将它们按顺序传递给将数据包装在 Card 中的辅助类。问题是这个实现将最新的文档放在底部,而我希望它们放在顶部。我可以更改从数据库中检索文档的顺序Firestore.instance.collection(path).orderBy('date', descending: true).getDocuments();,但是由于每次返回页面时列表都不会完全重建,因此除非我重建应用程序,否则新数据根本不会显示。我还尝试reverse: true在自定义滚动视图中进行设置,但这会反转所有内容,包括 SliverAppBar。

有什么方法可以翻转 SliverFixedExtentList 的构建方式,以便更高的索引位于顶部?

4

1 回答 1

2

而不是试图反转 SliverFixedExtentList,您可以反转项目...您所要做的就是在for each 循环之后反转_documents

注意我在哪里添加了_documents = _documents.reversed.toList()和 setState

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:project_spruce/DataBase/DataBaseConnection.dart';
import 'package:project_spruce/states/UserState.dart';
import 'package:project_spruce/widgets/FabBottomAppBar.dart';
import 'package:project_spruce/widgets/FoodItemCard.dart';
import 'package:provider/provider.dart';

class HomeScreen extends StatefulWidget {

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

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    final List<DocumentSnapshot> _documents = List<DocumentSnapshot>();
    String uid = Provider.of<UserState>(context).firebaseUser.uid;
    return FutureBuilder(
        future: Provider.of<DataBaseConnection>(context).getQuerySnapshot('eatenFoods/'+ uid +'/food'),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
          Widget child;
          if (snapshot.hasData){
            setState(() {
              _documents.clear();
              snapshot.data.documents.forEach((doc)=> _documents.add(doc));
              child = SliverFixedExtentList(
                itemExtent: 150,
                delegate: new SliverChildBuilderDelegate(
                      (context, index) => FoodItemCard(_documents[index]),
                  childCount: _documents.length,
                ),
              );
            });
          }else {
            child = SliverToBoxAdapter(child: CircularProgressIndicator());
          }
          return Scaffold(
              floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
              floatingActionButton: FloatingActionButton(
                onPressed: () => Navigator.pushNamed(context, '/camera_screen'),
                tooltip: 'Add',
                elevation: 2,
                child: Icon(Icons.add),
                backgroundColor: Theme.of(context).primaryColor,
                foregroundColor: Colors.white,
              ),
              bottomNavigationBar: FabBottomAppBar(
                backgroundColor: Theme.of(context).primaryColor,
                color: Colors.white,
                selectedColor: Colors.white,
                iconSize: 30,
                notchedShape: CircularNotchedRectangle(),
                items: [
                  FabBottomAppBarItem(iconData: Icons.search, text: 'Search'),
                  FabBottomAppBarItem(iconData: Icons.pie_chart, text: 'Statistics'),
                  FabBottomAppBarItem(
                      iconData: Icons.storage, text: 'Food Inventory'),
                  FabBottomAppBarItem(iconData: Icons.person, text: 'Profile'),
                ],
                onTabSelected: (int tabIndex) {
                  switch (tabIndex) {
                    case 0:
                      {
                        // Search
                        Navigator.pushNamed(context, '/search');
                      }
                      break;
                    case 1:
                      {
                        // Statistics
                        Navigator.pushNamed(context, '/stats');
                      }
                      break;
                    case 2:
                      {
                        // Inventory
                        Navigator.pushNamed(context, '/inventory');
                      }
                      break;
                    case 3:
                      {
                        // Profile
                        Navigator.pushNamed(context, '/profile');
                      }
                      break;
                  }
                },
              ),
              body: new CustomScrollView(
                slivers: <Widget>[
                  SliverAppBar(
                    //title: const Text('Home Page'),
                    actions: <Widget>[
                      IconButton(
                        icon: const Icon(Icons.notifications),
                        tooltip: 'Notifications',
                        onPressed: () => (){}, //(Navigator.pushNamed(context, '/notifications')),
                      ),
                    ],
                    floating: true,
                    pinned: true,
                    snap: false,
                    forceElevated: true,
                    expandedHeight: 200.0,
                    flexibleSpace: FlexibleSpaceBar(
                      title:
                      Text("Hi, " + Provider.of<UserState>(context).user.name),
                      centerTitle: false,
                    ),
                  ),
                  child,
                ],
              )
          );
        }
    );
  }
}

希望这有效

于 2020-03-16T18:18:46.940 回答