flutter - 如何将图标小部件转换为 ImageProvider

标签 flutter

我想在我的程序中使用 flutter 的 Material design 图标,为此,我需要使用 Icon widget。我有一个网络图像(NetworkImage 小部件),如果有一个空 URL,我想显示 Material design 图标。

Container(
      width: 48.0,
      height: 48.0,
      decoration: BoxDecoration(
          image: DecorationImage(
            image: imgLink.isEmpty
                ? Icon(Icons.person_outline)
                : NetworkImage(
                    imgLink,
                  ),
          ),
          borderRadius: BorderRadius.circular(10.0)),
    ),

它显示错误,因为图标不是 ImageProvider 的子类型。现在我如何将 Icon 转换为 ImageProvider 或任何其他方式。

最佳答案

解决方案是创建您自己的转换图标的提供程序:

import 'dart:ui' as ui;

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

class IconImageProvider extends ImageProvider<IconImageProvider> {
  final IconData icon;
  final double scale;
  final int size;
  final Color color;

  IconImageProvider(this.icon, {this.scale = 1.0, this.size = 48, this.color = Colors.white});

  @override
  Future<IconImageProvider> obtainKey(ImageConfiguration configuration) => SynchronousFuture<IconImageProvider>(this);

  @override
  ImageStreamCompleter load(IconImageProvider key, DecoderCallback decode) => OneFrameImageStreamCompleter(_loadAsync(key));

  Future<ImageInfo> _loadAsync(IconImageProvider key) async {
    assert(key == this);

    final recorder = ui.PictureRecorder();
    final canvas = Canvas(recorder);
    canvas.scale(scale, scale);
    final textPainter = TextPainter(textDirection: TextDirection.rtl);
    textPainter.text = TextSpan(
      text: String.fromCharCode(icon.codePoint),
      style: TextStyle(
        fontSize: size.toDouble(),
        fontFamily: icon.fontFamily,
        color: color,
      ),
    );
    textPainter.layout();
    textPainter.paint(canvas, Offset.zero);
    final image = await recorder.endRecording().toImage(size, size);
    return ImageInfo(image: image, scale: key.scale);
  }

  @override
  bool operator ==(dynamic other) {
    if (other.runtimeType != runtimeType) return false;
    final IconImageProvider typedOther = other;
    return icon == typedOther.icon && scale == typedOther.scale && size == typedOther.size && color == typedOther.color;
  }

  @override
  int get hashCode => hashValues(icon.hashCode, scale, size, color);

  @override
  String toString() => '$runtimeType(${describeIdentity(icon)}, scale: $scale, size: $size, color: $color)';
}

这是一个标准的 ImageProvider,所有库存的看起来都像这样。实际转换在 _loadAsync() 内进行。相当简单,只是一个普通的 Canvas 操作,将图标绘制为文本(实际上,它是 文本)。

关于flutter - 如何将图标小部件转换为 ImageProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63779906/

相关文章:

android - 无法启动 Observatory HTTP 服务器 Flutter/Dart

multithreading - 为什么在这段代码中,await 不会阻塞 ui

flutter - 安装 CMake 3.16.3 时需要 Objectbox Flutter/Dart CMake 3.11 或更高版本错误

android - 如何在Android Studio中为dart函数自动生成header comments?

flutter - Flutter Auth(BLoC模式和rxDart)?

android - android 应用程序类启动时运行 flutter 代码

dart - 为什么使用 List<T> 作为堆栈返回 _GrowableList

flutter - 如何将 'dart:ui' 图像渲染到 Flutter 中?

flutter - 我需要在 Flutter App 中的什么位置存储照片图像?

flutter - 为什么他们在实例名称中使用下划线?