所需插件
flutter_svg: ^2.0.9 #svg
flutter_cache_manager: ^3.4.0 #网络图像缓存
核心代码
ColorFilter.matrix 语句会对Svg 的颜色取反色。0~255反转。即使多色也不怕
SvgPicture.asset(
path,
colorFilter: Get.isDarkMode && autoColor
? ColorFilter.matrix([
-1, 0, 0, 0, 255, // Red
0, -1, 0, 0, 255, // Green
0, 0, -1, 0, 255, // Blue
0, 0, 0, 1, 0, // Alpha
])
: null,
width: size,
height: size,
);
svg.dart
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_svg/flutter_svg.dart';
///可随主题变化的Svg,简直太完美啦!无敌啦哥们
class ThemedSvgIcon extends StatelessWidget {
final String path;
final double size;
final bool isNetwork;
final bool autoColor; //因为不需要随主题变化的网络svg也有缓存的需求,故留此bool,如果你没有该需求,可以移除
///图标加载失败时 显示的展位符中的字 默认“牛”
final String errorText;
const ThemedSvgIcon(
{required this.path,
required this.size,
this.isNetwork = false,
this.autoColor = true,
this.errorText = "牛"});
Future<Uint8List?> _getSvgData(String url) async {
try {
// 获取缓存管理器实例
final fileInfo = await DefaultCacheManager().getSingleFile(url);
return fileInfo.readAsBytes();
} catch (e) {
print("Error fetching SVG: $e");
return null;
}
}
@override
Widget build(BuildContext context) {
if (isNetwork) return networkSvg();
return SvgPicture.asset(
path,
colorFilter: Theme.of(context).colorScheme.brightness == Brightness.dark && autoColor
? ColorFilter.matrix([
-1, 0, 0, 0, 255, // Red
0, -1, 0, 0, 255, // Green
0, 0, -1, 0, 255, // Blue
0, 0, 0, 1, 0, // Alpha
])
: null,
width: size,
height: size,
);
}
Widget networkSvg() {
return FutureBuilder<Uint8List?>(
future: _getSvgData(path),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return SvgPicture.memory(
snapshot.data!,
width: size,
height: size,
colorFilter: Theme.of(context).colorScheme.brightness == Brightness.dark && autoColor
? ColorFilter.matrix([
-1, 0, 0, 0, 255, // Red
0, -1, 0, 0, 255, // Green
0, 0, -1, 0, 255, // Blue
0, 0, 0, 1, 0, // Alpha
])
: null,
);
}
}
return Container(
width: size,
height: size,
decoration: BoxDecoration(
color: Colors.grey.withAlpha(50),
borderRadius: BorderRadius.all(Radius.circular(size / 6))),
child: Center(
child: Text(errorText, style: TextStyle(fontSize: size / 2))),
);
},
);
}
}
使用
Column(
children: [
//网络
ThemedSvgIcon(path:"https://cdn.hugeicons.com/icons/algorithm-stroke-rounded.svg",isNetwork: true,size: 32),
SizedBox(height: 4),
//本地
ThemedSvgIcon(path:AssetsSvgs.consoleDoublecolorMenuSvg, size: 32),
],
)