完成后的效果图是
不会意思发错了。
上篇博客已经介绍过,ListTile,我们这节依然用这个来实现。ListTile是StatelessWidget的组件。这个组件类似与android 里面的CheckedTextView吧。功能比较单一,显示纯文字或者类似我们现在做的这种checkText样式。
但是这个ListTile有个很大的局限,就是高度而且要求他的父代节点中必e Material widget。如果你要wrapcontent那种的话,这个肯定是不适合的。这个最多显示三行文本,高度是固定的,这个要记住。如果你要实现固定高度的,要使用Row。 isThreeLine属性可以把高度固定为三行文本。而且必须有subtitle结合使用,类似下面这种。
leading: const Icon(Icons.event_seat),这个可以在title前面添加图标。
trailing: const Icon(Icons.event_seat),这个可以在title后面添加图标。
为他添加一个图标也很简单。Icons官方库里面已经为我们自带了很多常用的图标了
(trailing这个属性,官网这样说的。意思是会显示在title后面,来生成一个icon组件
/// A widget to display after the title.
/// Typically an [Icon] widget.
我们现在上节实现的RandomWordsState新增一个set集合,来保存所有选中的
final List<WordPair> datas = <WordPair>[];
final Set<WordPair> selected = new Set<WordPair>(); //
修改creatItem方法
Widget creatItem(WordPair pair) { final bool alreadySaved = selected.contains(pair); // Add this line. return new ListTile( isThreeLine: true, subtitle: new Text( "这是副标题", style: _biggerFont, ), title: new Text( pair.asPascalCase, style: _biggerFont, ), trailing: new Icon( // Add the lines from here... alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), ); }
显示效果如下图:
下面我们为每个Item增加一个点击事件。实现onTap方法,这个很简单,在里面使用setState方法,使用这个是因为要刷新界面
onTap: (){ setState(() { if(alreadySaved){ selected.remove(pair); }else{ selected.add(pair); } }); },
这样就完成了第一个点击交互
是不是感觉显示的不够紧密,我们还有一个dense属性,给ListTile,然后再添加一个前置图标
leading: const Icon(Icons.add),
dense: true
再看看效果。是不是差别还蛮大的