从零开始写第一个Flutter app(四)——无限滑动的ListView

目录

本节目标

ListView是开发中比较常用到的控件,本节课的目标是实现一个无线滑动的ListView,每当滑到底部时会自动生成10条数据,这样永远也滑不完

完整实现代码

由于本节代码相比前面几节的代码稍多点,所以先贴代码加注释,可以先看代码知道个大致的实现,然后后面再讲解一些疑点难点,不会说直接讲代码片段会有点不知所云,有点懵逼

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

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

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

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

class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[]; // ListView用的数据源
  final _biggerFont = const TextStyle(fontSize: 18.0); // 字体大小

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(), // body为一个ListView
    );
  }

  Widget _buildSuggestions() {
    return ListView.builder(
        padding: const EdgeInsets.all(16.0), // 设置padding
        itemBuilder: (context, i) {
          if (i.isOdd) return Divider(); // 如果为基数,返回分割线

          final index = i ~/ 2; // 由于divider也占一个位置,所以需除以2计算实际的index
          // 若数据源不够,则一次性生成10条数据,这样就可以实现ListView无限滑动的效果
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10));
          }
          // 生成每一条item布局
          return _buildRow(_suggestions[index]);
        });
  }

  // 创建ListView的Item
  Widget _buildRow(WordPair pair) {
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }
}

代码解析

  • RandomWordsState改成返回Scaffold,Scaffold的body内容是由方法_buildSuggestions()返回的ListView
  • ListView由ListView.builder()类生成,里面的itemBuilder属性设置Item
  • 需注意,这里的分割线也算item,按顺序0、2、4、6等偶数位置是实际的item,1、3、5、7等奇数位置是分割线
  • if (i.isOdd) return Divider();判断如果是奇数就返回分割线
  • final index = i ~/ 2;是为了计算扣除分割线后实际的item的位置,比如0、1、2、3、4、5除以2后结果为0、0、1、1、2、2,在根据计算结果index从_suggestions里获取显示的内容
  • index >= _suggestions.length判断数据是否不够,若不够则通过generateWordPairs().take(10)生成10条数据添加到_suggestions中

  • _buildRow(WordPair pair)根据传入的WordPair返回一个ListTile控件,控件里面实际是一个Text控件,显示WordPair的内容。

运行结果

 

 

posted @ 2019-07-27 16:26  野猿新一  阅读(62)  评论(0编辑  收藏  举报