07.Flutter之创建无限滚动的list

Flutter之创建无限滚动的list

三.创建一个无限滚动的ListView

  • 1.在RandomWordsState使用一个 _suggestions 列表保存生成的单词对,同时使用一个TextStyle类型的变量 _biggerFont 来设置字体大小

    class RandomWordsState extends State {
    
      final List _suggestions =  [];
      final TextStyle _biggerFont = new TextStyle(fontSize: 18.0);
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        final wordPair = WordPair.random();
        return Text(wordPair.asPascalCase);
      }
    
    }
    
  • 2.在RandomWordsState类中创建一个 _buildSuggestions() 方法,此方法创建显示单词对的 ListView ,ListView 类提供了一个 builder 属性,builder中的itemBuilder属性的值是一个匿名函数,接受两个参数- BuildContext 和行迭代器 i。迭代器从 0 开始, 每调用一次该函数,i 就会自增 1 , 并且只要itemBuilder对应的匿名函数返回值不为空, 该匿名函数还会被调用一次

    Widget _buildSuggestions() {
        return new ListView.builder(
            padding: const EdgeInsets.all(16.0),
    
            // 对于每个建议的单词对都会调用一次 itemBuilder,
            // 然后将单词对添加到 ListTile 行中
            // 在偶数行,该函数会为单词对添加一个 ListTile row.
            // 在奇数行,该函数会添加一个分割线的 widget,来分隔相邻的词对。
            // 注意,在小屏幕上,分割线看起来可能比较吃力。
    
            itemBuilder: (BuildContext _context, int i) {
              // 在每一列之前,添加一个1像素高的分隔线widget
              if (i.isOdd) {
                return new Divider();
              }
    
              // 语法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整)
              // 比如 i 为:1, 2, 3, 4, 5 时,结果为 0, 1, 1, 2, 2,
              // 这可以计算出 ListView 中减去分隔线后的实际单词对数量
              final int index = i ~/ 2;
              print("index = $index, i = $i");
    
              // 如果是建议列表中最后一个单词对
              if (index >= _suggestions.length) {
                // ...接着再生成10个单词对,然后添加到建议列表
                _suggestions.addAll(generateWordPairs().take(10));
              }
    
              return _buildRow(_suggestions[index]);
    
              // listview中只生成了10个单词对
              // if(index < _suggestions.length) {
              //   return _buildRow(_suggestions[index]);
              // } else {
              //   return null;
              // }
            }
        );
    }
    
  • 3.在RandomWordsState类中添加_buildRow()方法,用于返回显示单词对的widget

    Widget _buildRow(WordPair pair) {
      return ListTile(
        title: Text(
          pair.asPascalCase,
          style: _biggerFont,
        ),
      );
    }
    
  • 4.在RandomWordsState类中直接返回通过_buildSuggestions()方法构建的无限滚动的listview

    Widget build(BuildContext context) {
      // TODO: implement build
      final wordPair = WordPair.random();
      _suggestions.addAll(generateWordPairs().take(10));
      return _buildSuggestions();
    }
    
  • 5.完整代码如下

    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) {
    //    final wordPair = new WordPair.random();
        return new MaterialApp(
          title: 'Welecom to Flutter',
          debugShowCheckedModeBanner: false, //去除右上角debug标识
          home: new Scaffold(
            appBar: new AppBar(
              title: new Text('Welecom to Flutter'),
            ),
            body: new Center(
    //          child: new Text('Hello World'),
    //          child: new Text(wordPair.asPascalCase),
                child: RandomWords(),
            ),
          ),
        );
      }
    
    }
    
    class RandomWords extends StatefulWidget {
    
      @override
      State createState() {
        return RandomWordsState();
      }
    
    
    }
    
    class RandomWordsState extends State {
    
      final List _suggestions =  [];
      final TextStyle _biggerFont = new TextStyle(fontSize: 18.0);
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        final wordPair = WordPair.random();
        _suggestions.addAll(generateWordPairs().take(10));
        return _buildSuggestions();
      }
    
      Widget _buildSuggestions() {
        return new ListView.builder(
            padding: const EdgeInsets.all(16.0),
    
            // 对于每个建议的单词对都会调用一次 itemBuilder,
            // 然后将单词对添加到 ListTile 行中
            // 在偶数行,该函数会为单词对添加一个 ListTile row.
            // 在奇数行,该函数会添加一个分割线的 widget,来分隔相邻的词对。
            // 注意,在小屏幕上,分割线看起来可能比较吃力。
    
            itemBuilder: (BuildContext _context, int i) {
              // 在每一列之前,添加一个1像素高的分隔线widget
              if (i.isOdd) {
                return new Divider();
              }
    
              // 语法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整)
              // 比如 i 为:1, 2, 3, 4, 5 时,结果为 0, 1, 1, 2, 2,
              // 这可以计算出 ListView 中减去分隔线后的实际单词对数量
              final int index = i ~/ 2;
              print("index = $index, i = $i");
    
              // 如果是建议列表中最后一个单词对
              if (index >= _suggestions.length) {
                // ...接着再生成10个单词对,然后添加到建议列表
                _suggestions.addAll(generateWordPairs().take(10));
              }
    
              return _buildRow(_suggestions[index]);
    
              // listview中只生成了10个单词对
              // if(index < _suggestions.length) {
              //   return _buildRow(_suggestions[index]);
              // } else {
              //   return null;
              // }
            }
        );
    
    
      }
    
      Widget _buildRow(WordPair pair) {
        return new ListTile(
          title: new Text(
            pair.asPascalCase,
            style: _biggerFont,
          ),
        );
      }
    
    }
    

你可能感兴趣的:(Flutter)