跳转至正文

占位符和网络图片淡入

如何淡入占位符和网络图片。

当使用默认的 Image widget 显示图片时,你可能会注意到图片只是在加载完后直接显示到屏幕上,用户可能会觉得这看起来不舒服。

此外,如果可以先展示占位符,待图片加载完成后淡入显示图片不是很酷么?可以使用 Flutter 自带的 FadeInImage widget 来实现这个功能。

FadeInImage 适用于任何类型的图片:内存中的,本地存储的,抑或是网络上的。

从内存加载占位符

#

请按照以下步骤,来将单像素的透明 PNG 作为占位图:

  1. 创建透明图像数据。

    导入 dart:convertdart:typed_data,然后从 Base64 编码的字符串中解码图像:

    dart
    import 'dart:convert';
    import 'dart:typed_data';
    final Uint8List transparentImage = base64Decode(
      'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4'
      'nGMAAQAABQABDQottAAAAABJRU5ErkJggg==',
    );
    
  2. 将图像数据用作占位符。

    将解码后的图像数据传递给 placeholder 参数:

    dart
    FadeInImage.memoryNetwork(
      placeholder: transparentImage,
      image: 'https://picsum.photos/250?image=9',
    ),
    

完整样例

#
dart
import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/material.dart';

final Uint8List transparentImage = base64Decode(
  'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4'
  'nGMAAQAABQABDQottAAAAABJRU5ErkJggg==',
);

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

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

  @override
  Widget build(BuildContext context) {
    const title = 'Fade in images';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(title: const Text(title)),
        body: Stack(
          children: <Widget>[
            const Center(child: CircularProgressIndicator()),
            Center(
              child: FadeInImage.memoryNetwork(
                placeholder: transparentImage,
                image: 'https://picsum.photos/250?image=9',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Fading In Image Demo

从本地存储加载占位符

#

请按照以下步骤,来将本地图像资源用作占位图:

  1. 将占位图添加到资源包中。

    在项目的 assets 目录中添加一张占位图,例如 assets/loading.gif。然后在项目的 pubspec.yaml 文件中声明该资源。更多详细信息,请参考 添加资源和图片

    yaml
    flutter:
      assets:
        - assets/loading.gif
    
  2. 将资源用作占位。

    将资源路径传递给 FadeInImage.assetNetwork 构造函数的 placeholder 参数:

    dart
    FadeInImage.assetNetwork(
      placeholder: 'assets/loading.gif',
      image: 'https://picsum.photos/250?image=9',
    ),
    

完整样例

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

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

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

  @override
  Widget build(BuildContext context) {
    const title = 'Fade in images';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(title: const Text(title)),
        body: Center(
          child: FadeInImage.assetNetwork(
            placeholder: 'assets/loading.gif',
            image: 'https://picsum.photos/250?image=9',
          ),
        ),
      ),
    );
  }
}

Asset fade-in