В обратном порядке в Flutter создается SliverFixedExtentList - PullRequest
0 голосов
/ 16 марта 2020

У меня есть 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,
              ],
            )
            );
      }
    );
  }
}

Будущее получает список документов из базы данных, а затем передает их по порядку вспомогательному классу, который упаковывает данные в карту. Проблема в том, что эта реализация помещает самые последние документы внизу, а я хочу, чтобы они были сверху. Я могу изменить порядок извлечения документов из базы данных Firestore.instance.collection(path).orderBy('date', descending: true).getDocuments();, но поскольку список не перестраивается полностью каждый раз, когда я возвращаюсь на страницу, новые данные вообще не отображаются, пока я не перестрою приложение. Я также попытался установить reverse: true в пользовательском представлении прокрутки, но это полностью изменяет все, включая SliverAppBar.

Есть ли какой-то способ, которым я могу просто перевернуть способ построения SliverFixedExtentList, чтобы более высокие индексы были на вершине?

1 Ответ

1 голос
/ 16 марта 2020

Вместо того чтобы пытаться сторнировать SliverFixedExtentList, вы можете сторнировать элементы ... Все, что вам нужно сделать, это стереть _документы после для каждого l oop

Обратите внимание, где я добавил _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,
                ],
              )
          );
        }
    );
  }
}

Надеюсь, это сработает

...