Firestore Stream / Future始终显示加载块

时间:2019-04-29 18:06:56

标签: firebase flutter google-cloud-firestore flutter-layout

如果您有一个带有BottomNavigationBar的应用程序,并且要从一个barItem切换到另一barItem并返回给您列出Stream或Future,则我已经将scaffoldKey用于BottomNavigationBar,将PageStorageKey用于列表...我想逐页加载(分页)多数民众赞成的集合,但是使用Future或StreamBuilder在此或海峡中获取相同的结果...

您总是首先看到加载...但是加载是从本地而不是从Firestore数据库进行的吧?有没有办法再次跳过此加载... ??

class ListPage extends StatefulWidget {
  final FirebaseAnalytics analytics;
  final FirebaseAnalyticsObserver observer;
  final Firestore firestore;

  ListPage({Key key, this.analytics, this.observer, this.firestore})
      : super(key: key);

  @override
  _ListPageState createState() => new _ListPageState();
}

class _ListPageState extends State<ListPage> {
  final Firestore firestore = Firestore();
  RemoteConfig remoteConfig;

  final TextEditingController _search = new TextEditingController();

  SearchTextBox _searchField;
  ScrollController controller;
  DocumentSnapshot _lastVisible;
  bool _isLoading;
  CollectionReference get homeFeeds => firestore.collection('collection');
  List<DocumentSnapshot> _data = new List<DocumentSnapshot>();
  final scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  void initState() {
    super.initState();

    Analytics().setCurrentScreen('collection', 'listPage');

    controller = new ScrollController()..addListener(_scrollListener);

    _isLoading = true;
    _getData();
  }

  Future<Null> _getData() async {
    QuerySnapshot data;
    if (_lastVisible == null) {
      data = await firestore
          .collection('collection')
          .orderBy('updated_at', descending: true)
          .limit(50)
          .getDocuments();
      print('lastVisible == null');
    } else {
      data = await firestore
          .collection('collection')
          .orderBy('updated_at', descending: true)
          .startAfter([_lastVisible['updated_at']])
          .limit(10)
          .getDocuments();
      print('lastVisible else');
    }

    if (data != null && data.documents.length > 0) {
      _lastVisible = data.documents[data.documents.length - 1];
      if (mounted) {
        setState(() {
          print('lastVisible != null &&  data.documents.length > 0');
          _isLoading = false;
          _data.addAll(data.documents);
        });
      }
    } else {
      setState(() => _isLoading = false);
//      scaffoldKey.currentState?.showSnackBar(
//        SnackBar(
//          content: Text('No more restaurants!'),
//        ),
//      );
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      key: scaffoldKey,
      body: ListView.builder(
        shrinkWrap: true,
        controller: controller,
        itemCount: _data.length + 1,
        itemBuilder: (_, int index) {
          if (index < _data.length) {
            return Column(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: ListTile(
                    isThreeLine: false,
                    key: PageStorageKey(index),
                    title: Text('text'),
                    subtitle: Text(
                      '${_data[index].data['name']} • ${_data[index].data['place']}',
                    ),
                    onTap: () {},
                    leading: InkWell(
                        child: Container(
                      height: 110.0,
                      width: 50.0,
                      child: Placeholder(),
                    )),
                  ),
                ),
                new Divider(
                  height: 2.0,
                ),
              ],
            );
          }
          return Center(
            child: Opacity(
              opacity: _isLoading ? 1.0 : 0.0,
              child: SizedBox(
                  width: 32.0,
                  height: 32.0,
                  child: CircularProgressIndicator()),
            ),
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    controller.removeListener(_scrollListener);
    super.dispose();
  }

  void _scrollListener() {
    if (!_isLoading) {
      double maxScroll = controller.position.maxScrollExtent;
      double currentScroll = controller.position.pixels;
      double delta = MediaQuery.of(context).size.height * 0.65;

      if (maxScroll - currentScroll < delta) {
        setState(() => _isLoading = true);
        _getData();
      }
    }
  }
}

0 个答案:

没有答案