Flutter 如何使用彩色图标

Flutter how can i use colorful icon

我有一个 BrandButton 小部件。它只是拿着带有品牌的登录按钮。它有图标、标签和一些颜色。在苹果中我可以使用 Icon(Icons.apple) 因为它会有白色的简单图标,facebook 也一样。但是在 google 中我想使用彩色的。那我该怎么做呢?我怎样才能制作自定义图标?我的自定义小部件不接受图像或什么。我该如何解决?谢谢大家的帮助!

我想要什么:

我的小工具:

class BrandButton extends StatelessWidget {
  final String label;
  final double height;
  final Color backgroundColor;
  final Color textColor;
  final Icon brandIcon;

  const BrandButton(
      {Key? key,
      this.label = "Sign in with Apple",
      this.height: 48,
      this.backgroundColor: Colors.black,
      required this.brandIcon,
      this.textColor: Colors.white})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: height,
      child: ElevatedButton(
          onPressed: () {},
          style: ButtonStyle(
            shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
            backgroundColor: MaterialStateProperty.all<Color>(backgroundColor),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              brandIcon,
              SizedBox(width: 15),
              Text(
                label,
                style: TextStyle(
                    color: textColor,
                    fontWeight: FontWeight.w500,
                    fontSize: 17,
                    height: 1.41),
              )
            ],
          )),
    );
  }
}

主要问题是,上面的另外两个是图标,你想要的是图片,所以你需要做的就是这里。

  1. 下载 Google 登录所需的资产。你可以使用这个 branding guidelines for it

  2. 您需要将资产添加到您的项目中。例如。您可以在根项目中有一个图像文件夹,并在图像文件夹中添加。

  3. 转到您的 pubspec.yaml 文件并将图像添加到资产下的项目:

assets:
   - images/google_logo.png
  1. 执行 flutter pub get 并确保图像已添加。
  2. 按如下方式更新您的 BrandButton 小部件:

主要区别是;

  • 您的品牌标志现在是一个小部件,因此您可以传递图像
  • 我将文本更改为必需文本而不是默认值。
  • 做了一些小的代码改进。

class BrandButton extends StatelessWidget {
  final String label;
  final double height;
  final Color backgroundColor;
  final Color textColor;
  final Widget brandIcon;

  const BrandButton({
    required this.brandIcon,
    required this.label,
    this.height = 48,
    this.backgroundColor = Colors.black,
    this.textColor = Colors.white,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: height,
      child: ElevatedButton(
        onPressed: () {},
        style: ButtonStyle(
          shape: MaterialStateProperty.all<RoundedRectangleBorder>(
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
          backgroundColor: MaterialStateProperty.all<Color>(backgroundColor),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            brandIcon,
            const SizedBox(width: 15),
            Text(
              label,
              style: TextStyle(
                  color: textColor,
                  fontWeight: FontWeight.w500,
                  fontSize: 17,
                  height: 1.41),
            )
          ],
        ),
      ),
    );
  }
}

您可以为Image创建另一个nullabe变量,它可以是图像路径的字符串或Image本身,并且使brandIconimage都可选。并在使用这些变量时执行 null。

在使用 BrandButton 时,您可以通过其中一个或两个,也可以优先显示一个。

class BrandButton extends StatelessWidget {
  final String label;
  final double height;
  final Color backgroundColor;
  final Color textColor;
  
  final Icon? brandIcon;
  final Image? image;

  const BrandButton({
    Key? key,
    this.label = "Sign in with Apple",
    this.height: 48,
    this.backgroundColor: Colors.black,
    this.textColor: Colors.white,
    this.image,
    this.brandIcon,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: height,
      child: ElevatedButton(
          onPressed: () {},
          style: ButtonStyle(
            shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
            backgroundColor: MaterialStateProperty.all<Color>(backgroundColor),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              if (image != null) image!,
              if (brandIcon != null) brandIcon!,
              SizedBox(width: 15),
              Text(
                label,
                style: TextStyle(
                    color: textColor,
                    fontWeight: FontWeight.w500,
                    fontSize: 17,
                    height: 1.41),
              )
            ],
          )),
    );
  }
}

Flutter 的图标列表中没有默认的 google 图标。那么,您可以做的是:

从这里下载一个 svg google 图标 icons8 for google icon

之后关注这篇文章。本文展示了如何为您的 Flutter 应用设置自定义图标:custom icon implementation.

如果以上不是你想要的,你可以按照Whosebug上的这个答案,它展示了如何为一个图标添加两种色调。您必须根据自己的需要编辑答案。但在我看来,以上只是简单得多。 stack answer

根据您的代码,您只需将 brandIcon 的类型从 Icon 转换为 Widget。然后创建一个自定义小部件并将其传递给 brandIcon 参数。

示例如下:

class BrandButton extends StatelessWidget {
  final String label;
  final double height;
  final Color backgroundColor;
  final Color textColor;
  final Widget brandIcon;

  const BrandButton(
      {Key? key,
      this.label = "Sign in with Apple",
      this.height: 48,
      this.backgroundColor: Colors.black,
      required this.brandIcon,
      this.textColor: Colors.white})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: height,
      child: ElevatedButton(
          onPressed: () {},
          style: ButtonStyle(
            shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
            backgroundColor: MaterialStateProperty.all<Color>(backgroundColor),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              brandIcon,
              SizedBox(width: 15),
              Text(
                label,
                style: TextStyle(
                    color: textColor,
                    fontWeight: FontWeight.w500,
                    fontSize: 17,
                    height: 1.41),
              )
            ],
          )),
    );
  }
}

并将其称为,

  BrandButton(
    brandIcon: Image.network('some icon image url'),
    )

您可以简单地使用图像小部件来显示资产中的图像,甚至可以使用 flutter_svg: ^1.0.3 包来显示 svg 文件