简体   繁体   English

Flutter ListView.builder Stutters并在Scroll上跳转到顶部

[英]Flutter ListView.builder Stutters and Jumps to Top on Scroll

Scrolling up from partway down the list makes the page jump to top. 从列表中间向下滚动使页面跳到顶部。 I'm using Flutter and Firestore, with a StreamBuilder to get the data. 我正在使用Flutter和Firestore,使用StreamBuilder来获取数据。

I've tried changing scroll physics, setting placeholders, and it doesn't seem to help. 我已经尝试过更改滚动物理,设置占位符,它似乎没有帮助。

  StreamBuilder<QuerySnapshot>(
    // Create a stream listening to the posts collection
    stream: widget.firestore
        .collection('posts')
        .orderBy('sequence', descending: false)
        .snapshots(),
    builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
      // When we don't have data yet (!...hasData), display the text "Loading..."
      if (!snapshot.hasData) return const Text('Loading...');
      final int messageCount = snapshot.data.documents.length;

      // When data is availible, load
      return new ListView.builder(
        //padding: EdgeInsets.all(3.0),
        itemCount: messageCount,
        itemBuilder: (_, int index) {
          final DocumentSnapshot document = snapshot.data.documents[index];
          if (document["type"] == "standard")
            return StandardCard(widget.firestore, document.documentID);
          else if (document["type"] == "text")
            return TextCard(widget.firestore, document.documentID);
          else if (document["type"] == "video")
            return VideoCard(widget.firestore, document.documentID);
          else
            return Card(
              // Database is incorrect
              child: Center(
                child: Text("[Missing sufficient information]"),
              ),
            );
        },
      );
    },
  ),

It scrolls smoothly when you scroll down, but jerks to the top on an up-scroll. 向下滚动时它会顺畅滚动,但在向上滚动时会向上滚动。

Here's a self-contained example. 这是一个独立的例子。

import 'dart:math';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ListView Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'ListView Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  stream() async* {
    yield ObjectHasFuture();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: StreamBuilder(
            stream: stream(),
            builder: (BuildContext context, snapshot) {
              if (!snapshot.hasData) return const Text('Loading...');
              return ListView.builder(
                itemBuilder: (_, int index) {
                  return Card(
                    child: snapshot.data,
                  );
                },
              );
            }));
  }
}

class ObjectHasFuture extends StatelessWidget {
  data() async {
    await Future.delayed(Duration(seconds: Random().nextInt(2)));
    return Container(
      height: 250,
      color: Colors.green,
      child: Center(
        child: Text(Random().nextInt(10000).toString()),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: data(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) return const Text("Loading");

          return snapshot.data;
        });
  }
}

Are you doing this in debug mode or release mode? 你是在调试模式还是发布模式下这样做? Debug mode sometimes demonstrates odd artifacts that go away in the final build. 调试模式有时会演示在最终构建中消失的奇怪工件。

If you are dealing with static data of very low number of list items, you can speed the list up using 如果您正在处理列表项数量非常少的静态数据,则可以使用加速列表

ListView(
          addAutomaticKeepAlives: true,
          ...
)

give it a scrollController: 给它一个scrollController:

Listview.builder(
  controller: ScrollController(),
  //
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM