flutter 使用 列表

接着《flutter 使用 Widget》拆分的代码。

编辑 RandomWords.dart 的代码:

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


class RandomWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new RandomWordsState();
  }
}


class RandomWordsState extends State<RandomWords> {
  final wordPair = new WordPair.random();
  final _suggestions = <WordPair>[];
  final _fontSize = new TextStyle(fontSize: 16.0);

  @override
  Widget build(BuildContext context) {
    return _buildSuggestions();
  }

  Widget _buildRow(WordPair pair){
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _fontSize,
      ),
    );
  }
  
  Widget _buildSuggestions(){
    _suggestions.addAll(generateWordPairs().take(20));
    return new ListView.builder(
        itemBuilder: (context,i){
          return _buildRow(_suggestions[i]);
        }
    );
  }
}

效果:

9E0115D8-EF47-4E52-9C1F-00D6AA6463AA

但是下滑的时候,超过 20个内容就会显示空白,一直空白下去。

所以我们需要告诉 _buildSuggestions 方法,我们需要绘制多少个 cell。

修改代码:

  Widget _buildSuggestions(){
    _suggestions.addAll(generateWordPairs().take(20));

    return new ListView.builder(
        itemBuilder: (context,i){
          if(i < _suggestions.length){
            return _buildRow(_suggestions[i]);
          }
        }
    );
  }

添加分割线

  Widget _buildSuggestions(){
    _suggestions.addAll(generateWordPairs().take(20));
    return new ListView.builder(
        itemBuilder: (context,i){
          if(i.isOdd){return new Divider();}//如果i是奇数,就添加分割线,如果是偶数,才添加带数据的row
          final index = i ~/ 2;//效果和整除差不多,i为0、1、2、3、4、5...,算到的index为0、0、1、1、2、2...
          //index的计算,主要是因为插入了分割线以后,迭代器迭代的次数是原来的双倍,一半是渲染分割线,一半是渲染带数据的row
          if(index < _suggestions.length){
            return _buildRow(_suggestions[index]);
          }
        }
    );
  }

效果:

696FE4A6-E2A6-42B2-A187-6AA9BA298940

交互操作

cell 添加右边 icon

加入 _saved 记录是否点击了 cell。

  final wordPair = new WordPair.random();
  final _suggestions = <WordPair>[];
  final _fontSize = new TextStyle(fontSize: 16.0);
  final _saved = new Set<WordPair>();
Widget _buildRow(WordPair pair){
    final aleardySaved = _saved.contains(pair);//判断是否包含当前单词,判断是否被赞
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _fontSize,
      ),
      trailing: new Icon(
        aleardySaved ? Icons.favorite : Icons.favorite_border,
        color: aleardySaved ? Colors.red:null,
      ),
    );
  }

效果:

0EEA35A6-2271-47B8-B520-01F7A3FE7D5D

Cell 加入触发事件

  Widget _buildRow(WordPair pair){
    final aleardySaved = _saved.contains(pair);//判断是否包含当前单词,判断是否被赞
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _fontSize,
      ),
      trailing: new Icon(
        aleardySaved ? Icons.favorite : Icons.favorite_border,
        color: aleardySaved ? Colors.red:null,
      ),
      onTap: () => _favourite(pair),
    );
  }

  void _favourite(WordPair pair){
    setState((){
      if(_saved.contains(pair)){
        _saved.remove(pair);
      }else{
        _saved.add(pair);
      }
    });
  }

效果:

F274C33C-F839-4983-9759-51831E865BE1

从 cell 跳转到新页面

void _favourite(WordPair pair){
    Navigator.of(context).push(
        new MaterialPageRoute(
            builder:(context){
              return new Scaffold(
                appBar: new AppBar(
                  title: new Text("Welcome to new page"),
                ),
                body: new Center(
                  child: new Text("new page"),
                ),
              );
            })
    );
  }

新页面效果:
437D1959-72AC-4A68-BAED-CBB01D21690F

在导航栏右边按钮进入新页面

RandomWordsState 类的部分代码:

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Startup Name Generator'),
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.list), onPressed: _pushNavi),
        ],
      ),
      body: _buildSuggestions(),
    );
  }

  void _pushNavi(){
    Navigator.of(context).push(
        new MaterialPageRoute(
            builder:(context){
              return new Scaffold(
                appBar: new AppBar(
                  title: new Text("Welcome to new page"),
                ),
                body: new Center(
                  child: new Text("new page"),
                ),
              );
            })
    );
  }

多了右边按钮的导航栏效果:

37B3BB9A-297B-4613-9F41-FF7626F2C4EE