在Flutter项目中ListView的滚动不流畅

时间:2018-07-10 13:33:32

标签: android ios listview flutter hybrid-mobile-app

我刚刚开始学习Flutter。而且我遇到了一个大问题,即在复杂列表中滚动不良。假设我们的ListView中有5种不同的项目类型,并且某些项目类型必须显示图像并且它是无限滚动的。我阅读了很多有关ListView for Flutter的文章和帖子,我所看到的所有内容都是带有文本的简单列表。如何平滑滚动?

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Startup Name Generator',
      home: new RandomWords(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => new RandomWordsState();
}

class RandomWordsState extends State<RandomWords> {
  final List<WordPair> _suggestions = <WordPair>[];
  final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);
  List<int> items = List.generate(10, (i) => i);
  ScrollController _scrollController = new ScrollController();
  bool isPerformingRequest = false;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        _getMoreData();
      }
    });
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  _getMoreData() async {
    if (!isPerformingRequest) {
      setState(() => isPerformingRequest = true);
      List<int> newEntries = await fakeRequest(
          items.length, items.length + 10); //returns empty list
      if (newEntries.isEmpty) {
        double edge = 50.0;
        double offsetFromBottom = _scrollController.position.maxScrollExtent -
            _scrollController.position.pixels;
        if (offsetFromBottom < edge) {
          _scrollController.animateTo(
              _scrollController.offset - (edge - offsetFromBottom),
              duration: new Duration(milliseconds: 500),
              curve: Curves.easeOut);
        }
      }
      setState(() {
        items.addAll(newEntries);
        isPerformingRequest = false;
      });
    }
  }

  Future<List<int>> fakeRequest(int from, int to) async {
    return Future.delayed(Duration(seconds: 1), () {
      return List.generate(to - from, (i) => i + from);
    });
  }

  Widget _buildProgressIndicator() {
    return new Padding(
      padding: const EdgeInsets.all(8.0),
      child: new Center(
        child: new Opacity(
          opacity: isPerformingRequest ? 1.0 : 0.0,
          child: new CircularProgressIndicator(),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text(""),
      ),
      body: ListView.builder(
        itemCount: items.length + 1,

        itemBuilder: (context, index) {

          if (index == items.length) {
            return _buildProgressIndicator();
          } else {
            if (index % 5 == 0) {
              return Image.network(
                "http://sanctum-inle-resort.com/wp-content/uploads/2015/11/Sanctum_Inl_Resort_Myanmar_Flowers_Frangipani.jpg",
                height: 200.0,
              );
            } else if (index.isOdd) {
              return Container(
                padding: EdgeInsets.all(16.0),
                child: ListTile(
                  leading: Icon(Icons.person),
                  title: Text('This is title'),
                ),
              );
            } else {
              return ListTile(title: new Text("Number $index"));
            }
          }
        },
        controller: _scrollController,
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:0)

我认为问题在于,当用户已经到达列表的末尾并且没有更多项时,您请求数据异步,然后它正在执行伪造的请求,该请求将加载数据,但这需要花费几秒钟的时间这就是为什么

_scrollController.position.maxScrollExtent

这将获得滚动列表的末尾,因此它会在用户位于列表末尾的位置开始加载,您可以更改此值的偏移量,以便更早开始加载

要对此进行测试,您可以尝试更改:

   if (_scrollController.position.pixels ==
      _scrollController.position.maxScrollExtent) {

收件人:

   if (_scrollController.position.pixels ==
      (_scrollController.position.maxScrollExtent - 50)) {

还有

  Future<List<int>> fakeRequest(int from, int to) async {
    return Future.delayed(Duration(seconds: 1), () {
      return List.generate(to - from, (i) => i + from);
    });
  }

收件人:

List<int> fakeRequest(int from, int to) {
         return List.generate(to - from, (i) => i + from);
      }