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]);
}
);
}
}
效果:
但是下滑的时候,超过 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]);
}
}
);
}
效果:
交互操作
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,
),
);
}
效果:
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);
}
});
}
效果:
从 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"),
),
);
})
);
}
新页面效果:
在导航栏右边按钮进入新页面
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"),
),
);
})
);
}
多了右边按钮的导航栏效果: