Reputation: 121
In my build
, I have this function that basically stacks a button
and a counter
, i'm also passing a function (this let's me reuse the buildbuttoncolumn
for all buttons instead of copying code arround
my build:
Widget build(BuildContext context) {
List<Widget> _layouts = [
_videoInfo(),
_channelInfo(),
_comment(),
_moreInfo(),
VideoList(
channel: widget.channel,
isMiniList: true,
currentVideoId: widget.detail.id
),
];
if (MediaQuery.of(context).orientation == Orientation.landscape) {
_layouts.clear();
}
return Scaffold(
body: Column(children: <Widget>[
_buildVideoPlayer(context),
Expanded(
child: ListView(
children: _layouts,
),
)
]));
}
my videoinfo:
Widget _videoInfo() {
return Column(
children: <Widget>[
ListTile(
title: Text(widget.detail.title),
subtitle: Text(widget.detail.viewCount + ' . ' + widget.detail.publishedTime),
trailing: Icon(Icons.arrow_drop_down),
),
Container(
padding: EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildButtomColumn(Icons.thumb_up, widget.detail.likeCount, function: _like(widget.detail.id, true)),
_buildButtomColumn(Icons.thumb_down, widget.detail.dislikeCount, function: _like(widget.detail.id, false)),
_buildButtomColumn(CupertinoIcons.share_up, "Partilhar"), //function: share(context, widget.detail.player)
_buildButtomColumn(Icons.add_to_photos, "Guardar"),
],
),
)
],
);
}
_buildButtomColumn(Icons.thumb_up, widget.detail.likeCount, function: _like(widget.detail.id, true)),
the method then does something like this:
Widget _buildButtomColumn(IconData icon, String text, {function}) {
return GestureDetector(
onTap: () => function
child: Column(.....
oh and here's the like:
_like(String videoId, bool liked) {
youtubeAPI.likeDislikeVideo(videoId, liked);
}
when I open the page, the onTap
gets triggered without me actually pressing the button.
Upvotes: 5
Views: 1449
Reputation: 1781
Where is the problem?
You are calling that function yourself, there is no problem with onTap
callback and it is not fired somehow without user interaction
Next snippet performs _like
function invocation and pass returned result to function:...
arg (refer to lang tour)
function: _like(widget.detail.id, true)
You can prevent such situations if you declare function:
argument type as Function
and you will get static analysis type error before you run code
_buildButtomColumn(IconData icon, String text, {Function function})
Back to you code - how to fix it?
Widget _buildButtomColumn(IconData icon, String text, {VoidCallback function}) {
/// here I enforced type as VoidCallback - it is typedef for `void Function()`
return GestureDetector(
onTap: function, // <-- pass function, onTap type is VoidCallback
child: Column(.....
2.a. pass anonymous function with desired payload
_buildButtomColumn(Icons.thumb_up, widget.detail.likeCount,
function: () => youtubeAPI.likeDislikeVideo(videoId, liked), // <-- this will be invoked later
)
2.b. this variant is for sake of completeness
declare callable class and pass it's instance to function:...
arg ()
class LikeCommand {
final String videoId;
final bool liked;
LikeCommand(this.videoId, this.liked);
void call() => youtubeAPI.likeDislikeVideo(videoId, liked);
}
_buildButtomColumn(Icons.thumb_up, widget.detail.likeCount,
function: LikeCommand(videoId, liked),
)
PS I recommend declaring types, since dart is a strongly typed language and specifying types will save you from typical problems in the future
PPS feel free to reach me in comments
Upvotes: 4