8
votes

Flutter ListView.builder bégaie et saute en haut lors du défilement

Faire défiler vers le haut à partir de la moitié de la liste fait sauter la page en haut. J'utilise Flutter et Firestore, avec un StreamBuilder pour obtenir les données.

J'ai essayé de changer la physique du défilement, de définir des espaces réservés, et cela ne semble pas aider.

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;
        });
  }
}


3 commentaires

Bonjour Nathan, as-tu trouvé la solution? J'ai le même problème.


@miloss En quelque sorte. Le déplacement de la logique basée sur les flux dans la méthode de création de List fonctionne dans une certaine mesure.


Résolu ce problème avec la réponse ici: stackoverflow.com/a/62462777/144857


3 Réponses :


0
votes

Faites-vous cela en mode débogage ou en mode version? Le mode de débogage montre parfois des artefacts étranges qui disparaissent dans la version finale.


1 commentaires

C'est en mode libération. Le mode de débogage n'est que légèrement plus saccadé qu'en mode de libération.



0
votes

Si vous avez affaire à des données statiques d'un très petit nombre d'éléments de liste, vous pouvez accélérer la liste en utilisant

ListView(
          addAutomaticKeepAlives: true,
          ...
)


0 commentaires

0
votes

donnez-lui un scrollController:

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


0 commentaires