Skip to content

图片和图标

Image 图片组件

Flutter 中,我们可以通过 Image 组件来加载并显示图片 Image 的数据源可以是 asset、文件、内存以及网络

  • Image.asset, 本地图片
  • Image.network 远程图片

Image 常用属性

名称类型说明
alignmentAlignment图片的对齐方式
color 和 colorBlendMode设置图片的背景颜色,通常和 colorBlendMode 配合一起使用,这样可以是图片颜色和背景色混合。上面的图片就是进行了颜色的混合,绿色背景和图片红色的混合
fitBoxFitfit 属性用来控制图片的拉伸和挤压,这都是根据父容器来 的。 BoxFit.fill:全图显示,图片会被拉伸,并充满父容器。 BoxFit.contain:全图显示,显示原比例,可能会有空隙。 BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。 BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。 BoxFit.fitHeight :高度充满(竖向充满),显示可能拉伸,可能裁切。 BoxFit.scaleDown:效果和 contain 差不多,但是此属性不允许显示超过源图片大小,可小不可大。
repeat平铺ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。ImageRepeat.repeatX: 横向重复,纵向不重复。 ImageRepeat.repeatY:纵向重复,横向不重复。
width宽度 一般结合 ClipOval 才能看到效果
height高度 一般结合 ClipOval 才能看到效果

加载远程图片

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        // mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // 网络图片
          Container(
            alignment: Alignment.center,
            width: 150,
            height: 150,
            margin: const EdgeInsets.fromLTRB(0, 20, 0, 0),
            decoration: const BoxDecoration(
              color: Colors.yellow,
              borderRadius: BorderRadius.all(Radius.circular(75)),
            ),
            child: ClipOval(
              child: Image.network(
                "https://doc.ronhai.com/bg.png",
                fit: BoxFit.cover,
                width: 150,
                height: 150,
              ),
            ),
          ),
          // Container实现圆形图片
          const SizedBox(
            height: 20,
          ),
        ],
      ),
    );
  }
}

image-20241226154108767

Container 实现圆形图片

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          Container(
            width: 150,
            height: 150,
            decoration: BoxDecoration(
                color: Colors.red,
                borderRadius: BorderRadius.circular(75),
                image: const DecorationImage(
                    image: NetworkImage('https://doc.ronhai.com/bg.png'),
                    fit: BoxFit.cover)),
          )
        ],
      ),
    );
  }
}

image-20241226162948490

ClipOval 实现圆形图片

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          ClipOval(
              child: Image.network(
            'https://www.ronhai.com/media/images/article/flutter.png',
            fit: BoxFit.cover,
            width: 45,
            height: 45,
          )),
        ],
      ),
    );
  }
}

image-20241226163243599

CircleAvatar 实现圆形图片

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Column(
        children: [
          CircleAvatar(
            radius: 100,
            backgroundImage: NetworkImage(
                'https://www.ronhai.com/media/images/article/flutter.png'),
          )
        ],
      ),
    );
  }
}

基本上,CircleAvatar 不提供设置边框的属性。但是,可以将其包裹在具有更大半径和不同背景颜色的 不同 CircleAvatar 中,以创建类似于边框的内容

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Column(
        children: [
          CircleAvatar(
            radius: 110,
            backgroundColor: Colors.red,
            child: CircleAvatar(
              radius: 80,
              backgroundImage: NetworkImage(
                  'https://www.ronhai.com/media/images/article/flutter.png'),
            ),
          )
        ],
      ),
    );
  }
}

image-20241226163813648

加载本地图片

在项目的根目录新建 images 放入本地图片,设置pubspec.yamlassets

yaml
name: flutter_image
description: "A new Flutter project."

publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1

environment:
  sdk: ^3.5.4
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.8

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^4.0.0

flutter:
  uses-material-design: true
  #本地图片设置
  assets:
    - images/2.jpg
    - images/avatar.jpg
    - images/bannar.jpg
    - images/travel.jpg
    - images/web.jpg

使用

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Column(
        children: [
          //  本地图片
          Icon(Icons.home),
          SizedBox(
            height: 20,
          ),
          Icon(
            Icons.people,
            color: Colors.pink,
          ),
        ],
      ),
    );
  }
}

image-20241226154430034

图标组件

使用 Flutter 官方 Icons 图标

Material Design 所有图标可以在其官网查看:https://material.io/tools/icons/

阿里巴巴图标库

Flutter 中借助阿里巴巴图标库自定义字体图标

我们也可以使用自定义字体图标。阿里巴巴图标库官网 iconfont.cn 上有很多字体图标素材,我们可以选择自己需要的图标打包下载后,会生成一些不同格式的字体文件,在 Flutter 中,我们使用 ttf 格式即可。

假设我们项目中需要使用一套图标,我们打包下载后导入

image-20240716103611671

image-20240716103651884

也可以配置多个字体文件

dart
  fonts:
    - family: iconfont
      fonts:
        - asset: assets/fonts/iconfont.ttf
   - family: myicon
      fonts:
        - asset: assets/fonts/myicon.ttf

为了使用方便,我们定义一个 MyIcons 类,功能和 Icons 类一样:将字体文件中的所有图标都定义成静态变量

dart
import 'package:flutter/material.dart';

class IconFont {
  static const IconData view = IconData(
    0xe633,
    fontFamily: 'iconfont',
    matchTextDirection: true,
  );
  static const IconData message = IconData(
    0xe635,
    fontFamily: 'iconfont',
    matchTextDirection: true,
  );
}

使用

dart
import 'package:flutter/material.dart';
import 'common/iconfont.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Flutter Demo'),
          ),
          body: Center(
            child: Container(
                alignment: Alignment.center,
                width: 300,
                height: 300,
                child: const Column(
                  children: [
                    Icon(
                      IconFont.view,
                      size: 30,
                      color: Colors.amber,
                    ),
                    Icon(
                      IconFont.message,
                      size: 30,
                      color: Colors.amber,
                    )
                  ],
                )),
          )),
    );
  }
}

image-20240716103716547

脚本生成 iconfont.dart 文件

新建generate_icons.dart文件放入 common 文件夹中,增加以下内容:

使用Code Runner运行脚本即可

dart
import 'dart:convert';
import 'dart:io';

String toCamelCase(String name) {
  List<String> parts = name.split(RegExp(r'[-_]'));
  String camelCaseName = parts[0];
  for (int i = 1; i < parts.length; i++) {
    camelCaseName += parts[i][0].toUpperCase() + parts[i].substring(1);
  }
  return camelCaseName;
}

void generateIconFontClass(String jsonFilePath, String outputFilePath) {
  File jsonFile = File(jsonFilePath);
  if (!jsonFile.existsSync()) {
    print('JSON file not found: $jsonFilePath');
    return;
  }

  String jsonString = jsonFile.readAsStringSync();
  Map<String, dynamic> jsonData = jsonDecode(jsonString);

  StringBuffer buffer = StringBuffer();
  buffer.writeln("import 'package:flutter/material.dart';\n");
  buffer.writeln("class IconFont {");

  if (jsonData.containsKey('glyphs')) {
    List<dynamic> glyphs = jsonData['glyphs'];
    glyphs.forEach((glyph) {
      if (glyph.containsKey('unicode_decimal') && glyph.containsKey('name')) {
        String name = glyph['name'];
        int unicode = glyph['unicode_decimal'];
        // String fontClass = glyph['font_class'];

        String fieldName = toCamelCase(name);

        buffer.writeln("  static const IconData $fieldName = IconData(");
        buffer.writeln("    0x${unicode.toRadixString(16)},");
        buffer.writeln("    fontFamily: 'iconfont',");
        buffer.writeln("    matchTextDirection: true,");
        buffer.writeln("  );");
      }
    });
  }

  buffer.writeln("}");

  // Write generated code to output file
  File outputFile = File(outputFilePath);
  outputFile.writeAsStringSync(buffer.toString());

  print('IconFont class generated successfully at: $outputFilePath');
}

void main() {
  String jsonFilePath = 'assets/fonts/iconfont.json';
  String outputFilePath = 'lib/common/iconfont.dart';
  generateIconFontClass(jsonFilePath, outputFilePath);
}

引用

dart
 const Icon(
   IconFont.view,
   color: Colors.red,
   size: 30,
 )