首页 > 解决方案 > 尝试通过传递到 Flutter 中的自定义小部件的回调来启动外部 url

问题描述

我有一个网站按钮的小部件。

class WebsiteButton extends StatelessWidget {
  final String url;
  final Future<void> launchCallback;

  WebsiteButton(this.url, this.launchCallback);

  @override
  Widget build(BuildContext context) {
    if (url != null && url.isNotEmpty) {
      return IconButton(
        icon: Icon(FontAwesomeIcons.globe),
        tooltip: url,
        onPressed: () => launchCallback,
      );
    } else {
      return IconButton(
        icon: Icon(FontAwesomeIcons.globe),
        onPressed: null,
      );
    }
  }
}

为了使其更可重用(例如,如果我想在 webview 而不是浏览器中设置启动 url 的不同逻辑),我试图将回调传递_launch给小部件,如下所示:

    Future<void> _launch(String url) async {
      if (await canLaunch(url)) {
        await launch(
          url,
          forceSafariVC: false,
          forceWebView: false,
        );
      } else {
        throw 'Could not launch $url';
      }
    }
    ...
    WebsiteButton(
      profile.website,
      _launch(profile.website)
    ),

这会导致一种奇怪的行为:一旦构建了包含小部件的页面,就会启动 url,而不是IconButton像我预期的那样单击。我错过了什么?

(Flutter master v1.12.16-pre.35, url_launcher: 5.2.7)

标签: flutterdart

解决方案


看起来您作为参数传递给小部件的方法在您传递它时正在被调用。如果您进行了其他评论建议的更改,并且还使用匿名函数调用 _launch 方法,并将 url 字符串作为小部件的参数。

所以,它看起来像这样:

WebsiteButton(
    profile.website,
    () => _launch(profile.website)
)

或者您可以将 url 和 _launch 方法传递给 WebsiteButton,然后使用 WebsiteButton 中的 url 调用 _launch。


推荐阅读