codelabsの「Write Your First Flutter App, part 2」ではタップをListTile全体で取得していますが、
codelabs.developers.google.com
Tile全体のタップではなく、Iconのタップだけを認識するようにします。
結論
IconButton
を使う。
問題
codelabsのサンプルアプリでは、タップイベントをonTap
で取得しています。
onTap
はListTileへ結びついているため、Tileのどこをタップしてもハートの色が変化します。
これだとTile内でタップイベントを分けたい場合は困ります。
Widget _buildRow(WordPair pair) { final alreadySaved = _saved.contains(pair); return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), trailing: Icon( alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), onTap: () { setState(() { if (alreadySaved) { _saved.remove(pair); } else { _saved.add(pair); } }); }, ); }
解決策
trailing
に表示するものをIcon
ではなくIconButton
にすることで簡単に解決できます。
具体的にはtrailing
へIconButton
を指定し、IconButton
の中でIcon
とタップイベント取得用のonPressed
を記載します。
Widget _buildRow(WordPair pair) { final bool alreadySaved = _saved.contains(pair); return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), trailing: IconButton( icon: Icon(alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null), onPressed: () { setState(() { if (alreadySaved) { _saved.remove(pair); } else { _saved.add(pair); } }); }, ), ); }
シンプルに、アイコンをボタンにすればいいよねってことです。
試せていませんがContainer
でウィジェットを分けてからクリックリスナーを付けることもできると思います。
参考
ListTileについてはこのページがわかりやすいです。
ListTile class - material library - Dart API