Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase 如何在listview中添加更多滚动项目?_Firebase_Flutter_Google Cloud Firestore_Flutter Layout - Fatal编程技术网

Firebase 如何在listview中添加更多滚动项目?

Firebase 如何在listview中添加更多滚动项目?,firebase,flutter,google-cloud-firestore,flutter-layout,Firebase,Flutter,Google Cloud Firestore,Flutter Layout,此代码当前加载存储在Firestore集合中的所有啤酒。。我怎样才能在开始时只加载10杯啤酒,然后在用户向下滚动并到达10杯啤酒列表的末尾时加载。在最后一杯啤酒之后,应该再加载10杯。并且应该根据时间戳对啤酒进行排序 class BrewList extends StatefulWidget { @override _BrewListState createState() => _BrewListState(); } class _BrewListState extends St

此代码当前加载存储在Firestore集合中的所有啤酒。。我怎样才能在开始时只加载10杯啤酒,然后在用户向下滚动并到达10杯啤酒列表的末尾时加载。在最后一杯啤酒之后,应该再加载10杯。并且应该根据时间戳对啤酒进行排序

class BrewList extends StatefulWidget {
  @override
  _BrewListState createState() => _BrewListState();
}

class _BrewListState extends State<BrewList> {
  List<Brew> brews = [];
   ScrollController _controller = ScrollController();

  @override
  void initState() {
    _startFirst();
    super.initState();
    _controller.addListener(_scrollListener);
  }

       _scrollListener() {
    setState(() {
      if (_controller.position.atEdge) {
        if (_controller.position.pixels == 0) {


        } else {



        }
      }
    });
  }



 _startFirst() async {
    brews = await DatabaseService().brews ?? [];
    setState(() {
      brews = brews;

    });
  }

  @override
  Widget build(BuildContext context) {
    Future<void> _refreshBrews() async {
      List<Brew> tempList = await DatabaseService().brews;
      setState(() {
        brews = tempList;
      });
      print(brews);
    }


    return RefreshIndicator(
      onRefresh: _refreshBrews,
      child: ListView.builder(
        controller: _controller,
        itemCount: brews.length,
        itemBuilder: (context, index) {
          return BrewTile(brew: brews[index]);
        },
      ),
    );
  }
}


Future<List<Brew>> get brewss async {
    QuerySnapshot snapshot = await brewsCollection
        .orderBy('timestamp', descending: true)
          .limit(2)
        .getDocuments();

    return _postListFromSnapshot(snapshot);
  }
类BrewList扩展StatefulWidget{
@凌驾
_BrewListState createState()=>\u BrewListState();
}
类_BrewListState扩展了状态{
列表酿造=[];
ScrollController_controller=ScrollController();
@凌驾
void initState(){
_startFirst();
super.initState();
_controller.addListener(_scrollListener);
}
_scrollListener(){
设置状态(){
if(_controller.position.atEdge){
如果(_controller.position.pixels==0){
}否则{
}
}
});
}
_startFirst()异步{
brews=等待DatabaseService().brews???[];
设置状态(){
酿造=酿造;
});
}
@凌驾
小部件构建(构建上下文){
Future\u refreshBrews()异步{
List templast=wait DatabaseService().brews;
设置状态(){
酿造=圣堂武士;
});
印刷品(酿造);
}
返回刷新指示器(
onRefresh:_refreshBrews,
子项:ListView.builder(
控制器:_控制器,
itemCount:brews.length,
itemBuilder:(上下文,索引){
返回BrewTile(brew:brews[index]);
},
),
);
}
}
未来获取BREWS异步{
QuerySnapshot snapshot=wait brewsCollection
.orderBy('timestamp',降序:true)
.限额(2)
.getDocuments();
返回_postlistfromsapshot(快照);
}

您可以使用滚动控制器和侦听器来确定用户是否已滚动到屏幕底部。如果有,则从数据库服务加载接下来的10项

这看起来像下面这样

ScrollController _controller = ScrollController(); 

@override
void initState() {
  super.initState();
  // add listener
  _controller.addListener(_scrollListener);
}

_scrollListener() {
  setState(() {
    if (_controller.position.atEdge) {
      if (_controller.position.pixels == 0)
      {
        // user is at top of the list
      }
      else 
      {
        // user is at the bottom of the list.
        // load next 10 items and add them to the list of items in the list.
       }
    }
 });
}

不确定以下内容是否有用,但以下是我在颤振应用程序中所做的。请特别注意底部的_onScroll函数

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../blocs/feed_bloc/feed_events.dart';
import '../../blocs/feed_bloc/bloc.dart';
import '../../blocs/feed_bloc/feed_state.dart';
import './post.dart';
import '../loader.dart';

class Feed extends StatefulWidget {
  Feed({ Key key }): super(key: key);

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

class _FeedState extends State<Feed> {
  final _scrollController = ScrollController();
  final _scrollThreshold = 300.0;
  FeedBloc _feedBloc;

  _FeedState();

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_onScroll);
    _feedBloc = BlocProvider.of<FeedBloc>(context);
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<FeedBloc, FeedState>(
      builder: (context, state) {
        if (state is FeedUninitialized) {
          _feedBloc.add(Init());
          return Loader();
        }

        if (state is FeedLoading) {
          return Loader();
        }

        if (state is FeedLoaded) {
          return new RefreshIndicator(
            child: ListView(
              controller: _scrollController,
              // Important: Remove any padding from the ListView.
              padding: EdgeInsets.zero,
              children: state.posts.map((post) {
                return Post(
                  postModel: state.postMap[post]
                );
              }).toList(),
            ),
            onRefresh: () {
              _feedBloc.add(Refresh());
              return new Future.delayed(new Duration(seconds: 1));
            },
          );
        }


        return Center(
          child: SizedBox(
            height: 33,
            child: Text(
              'Sorry, there was a problem loading the feed.',
              style: TextStyle( color: Colors.white)
            ),
          ),
        );
      }
    );
  }

  int lastScroll = 0;
  void _onScroll() {
    if (new DateTime.now().millisecondsSinceEpoch - lastScroll > 1000) {
      lastScroll = new DateTime.now().millisecondsSinceEpoch;
      final maxScroll = _scrollController.position.maxScrollExtent;
      final currentScroll = _scrollController.position.pixels;
      if (maxScroll - currentScroll <= _scrollThreshold) {
        _feedBloc.add(Fetch());
      }
    }
  }
}
导入“包装:颤振/材料.省道”;
进口“包装:颤振团/颤振团.飞镖”;
导入“../../blocs/feed_bloc/feed_events.dart”;
导入“../blocs/feedu bloc/bloc.dart”;
导入“../../blocs/feed_bloc/feed_state.dart”;
导入“/post.dart”;
导入“../loader.dart”;
类提要扩展了StatefulWidget{
Feed({Key}):super(Key:Key);
@凌驾
_FeedState createState();
}
类_FeedState扩展状态{
final _scrollController=scrollController();
最终阈值=300.0;
feedblocu FeedBloc;
_FeedState();
@凌驾
void initState(){
super.initState();
_scrollController.addListener(_onScroll);
_feedBloc=BlocProvider.of(上下文);
}
@凌驾
小部件构建(构建上下文){
返回BlocBuilder(
生成器:(上下文、状态){
如果(状态为FeedUninitialized){
_add(Init());
返回加载器();
}
如果(状态为FeedLoading){
返回加载器();
}
如果(状态为FeedLoaded){
返回新的刷新指示器(
子:ListView(
控制器:\ u滚动控制器,
//重要提示:从ListView中删除任何填充。
填充:EdgeInsets.zero,
子项:state.posts.map((post){
回程站(
postModel:state.postMap[post]
);
}).toList(),
),
onRefresh:(){
_添加(刷新());
返回新的未来。延迟(新的持续时间(秒:1));
},
);
}
返回中心(
孩子:大小盒子(
身高:33,
子:文本(
“抱歉,加载提要时出现问题。”,
样式:TextStyle(颜色:Colors.white)
),
),
);
}
);
}
int lastcoll=0;
void _onScroll(){
if(new DateTime.now().millissecondssinceepoch-lastcoll>1000){
lastScroll=new DateTime.now().millissecondssinceepoch;
final maxScroll=\u scrollController.position.maxScrollExtent;
最终currentScroll=\u scrollController.position.pixels;

如果(maxScroll-currentScroll)首先你只想获取10个项目?可能是20个。但是我想在scroll上加载更多项目。非常感谢。但是你可以简化一下吗。我只是一个初学者,这看起来有点复杂。@pskinkyu有一个完整的工作小部件,只需使用它将来获取brews async{QuerySnapshot snapshot=wait brewsCollection.orderBy('timestamp',降序:true).getDocuments();返回_brewlistfromsapshot(snapshot);}这就是我获取当前列表的方式..我添加了scrollController..您是否可以向我展示我需要在此处添加的功能?您是指如何一次从firestore获取10个项目?最初使用上述代码..它加载列表中的所有啤酒..但我最初只想加载10个啤酒,然后在用户到达lis末尾时加载最初加载了10杯啤酒中的一杯..我想再加载10杯,以此类推..这与您如何使用某种查询对存储在firestore中的数据进行分页有关。我发现您之前已经询问过这一问题,并得到了合理的答案。基本上,您需要能够编写查询,以获得10块的文档。如果您有在文档上创建一个自动递增的整数属性,您可以通过该属性进行排序,然后最初选择该属性在0和11之间的位置。然后在第二个查询中,在10和21之间进行排序。这并没有回答我的问题,但感谢您所做的努力。我正在尝试找出如何排序从()开始的下一组数据最初加载到屏幕上的最后一组数据。@alex我明白了。我编辑了我的答案以包含c
Future<Map<String, dynamic>> getPosts({PostModel parent, PostModel lastPost}) async {
    // First, we create the initial query. 
    // We pass in the parent key if there is one.
    Query query = Firestore.instance
      .collection('posts');

      if (parent != null) {
        query = query.where('parentId', isEqualTo: parent.key);
      } else {
        query = query.where('parentId', isNull: true);
      }

      query = query.orderBy('timestamp', descending: true);

    // If we want to start at a certain doc (user is scrolling throught he feed)
    // then we specify to start after a certain doc
    if (lastPost != null) {
      query = query.startAfterDocument(lastPost.rawDoc);
    }

    // Execute the query
    final results = await query
      .limit(18)
      .getDocuments();

    // Create some Lists/Maps we're going to need
    List<String> posts = new List<String>();
    Map<String, PostModel> postMap = new Map<String, PostModel>();
    Map<String, bool> likeMap = new Map<String, bool>();

    // Convienience/Brevity 
    final List<DocumentSnapshot> documents = results.documents;
    final int numDocs = documents.length;

    if (numDocs > 0) {
      final firstDoc = results.documents[0].data;
      final lastDoc = results.documents[numDocs-1].data;

      // Get all your likes for a certain date range that aligns with the
      // documents we just retrieved
      likeMap = await getLikes(firstDoc['postCreated'], lastDoc['postCreated']);
    }

    // Loop through, and create all the PostModels
    for (int i = 0; i < numDocs; i++) {
      DocumentSnapshot doc = documents[i];
      PostModel post = snapshotToPostModel(doc, likeMap[doc.documentID]);
      postMap[doc.documentID] = post;
      posts.add(post.key);
    }

    final Map<String, dynamic> res = new Map<String, dynamic>();

    res['posts'] = posts;
    res['postMap'] = postMap;

    return res;
  }