Flutter图片渐变效果插件image_fade的使用
Flutter图片渐变效果插件image_fade的使用
ImageFade
是一个用于Flutter的widget,它可以在指定的 image
加载时显示一个 placeholder
widget,然后交叉淡入到加载完成的图片。同时它还处理进度和错误情况。当合适时,它会使用 Image.opacity
以提高性能。
如果 image
发生变化,它会在新图片加载完成后淡入到新的图片。将 image
设置为 null
将淡回到占位符。
你可以设置 duration
和 curve
,以及大多数 Image
的属性:width
、height
、fit
、alignment
、repeat
、matchTextDirection
、excludeFromSemantics
和 semanticLabel
。
使用 loadingBuilder
和 errorBuilder
来显示加载进度或错误状态。还可以通过指定 syncDuration
来使用不同的(通常是更快的)持续时间来淡入同步加载的图像、错误或占位符。
示例代码
下面是一个完整的示例demo,展示了如何使用 ImageFade
插件:
import 'package:flutter/material.dart';
import 'package:image_fade/image_fade.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.yellow,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// Sample images from Wikimedia Commons:
static const List<String> _imgs = [
'https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Almeida_Júnior_-_Saudade_%28Longing%29_-_Google_Art_Project.jpg/513px-Almeida_Júnior_-_Saudade_%28Longing%29_-_Google_Art_Project.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Rafael_-_Retrato_de_um_Cardeal.jpg/786px-Rafael_-_Retrato_de_um_Cardeal.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/James_McNeill_Whistler_-_La_Princesse_du_pays_de_la_porcelaine_-_brighter.jpg/580px-James_McNeill_Whistler_-_La_Princesse_du_pays_de_la_porcelaine_-_brighter.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Hans_Holbein_der_Jüngere_-_Der_Kaufmann_Georg_Gisze_-_Google_Art_Project.jpg/897px-Hans_Holbein_der_Jüngere_-_Der_Kaufmann_Georg_Gisze_-_Google_Art_Project.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Pieter_Bruegel_the_Elder_-_The_Tower_of_Babel_%28Vienna%29_-_Google_Art_Project_-_edited.jpg/1280px-Pieter_Bruegel_the_Elder_-_The_Tower_of_Babel_%28Vienna%29_-_Google_Art_Project_-_edited.jpg',
];
int _counter = 0;
bool _clear = true;
bool _error = false;
void _incrementCounter() {
setState(() {
if (_clear || _error) {
_clear = _error = false;
} else {
_counter = (_counter + 1) % _imgs.length;
}
});
}
void _clearImage() {
setState(() {
_clear = true;
_error = false;
});
}
void _testError() {
setState(() => _error = true);
}
@override
Widget build(BuildContext context) {
String? url;
if (_error) {
url = 'error.jpg';
} else if (!_clear) {
url = _imgs[_counter];
}
String title = _error
? 'error'
: _clear
? 'placeholder'
: 'image #$_counter from Wikimedia';
return Scaffold(
appBar: AppBar(title: Text('Showing ' + title)),
body: Stack(children: <Widget>[
Positioned.fill(
child: ImageFade(
// whenever the image changes, it will be loaded, and then faded in:
image: url == null ? null : NetworkImage(url),
// slow-ish fade for loaded images:
duration: const Duration(milliseconds: 900),
// if the image is loaded synchronously (ex. from memory), fade in faster:
syncDuration: const Duration(milliseconds: 150),
// supports most properties of Image:
alignment: Alignment.center,
fit: BoxFit.cover,
scale: 2,
// shown behind everything:
placeholder: Container(
color: const Color(0xFFCFCDCA),
alignment: Alignment.center,
child: const Icon(Icons.photo, color: Colors.white30, size: 128.0),
),
// shows progress while loading an image:
loadingBuilder: (context, progress, chunkEvent) =>
Center(child: CircularProgressIndicator(value: progress)),
// displayed when an error occurs:
errorBuilder: (context, error) => Container(
color: const Color(0xFF6F6D6A),
alignment: Alignment.center,
child: const Icon(Icons.warning, color: Colors.black26, size: 128.0),
),
))
]),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Next',
child: const Icon(Icons.navigate_next),
),
const SizedBox(width: 10.0),
FloatingActionButton(
onPressed: _clearImage,
tooltip: 'Clear',
child: const Icon(Icons.clear),
),
const SizedBox(width: 10.0),
FloatingActionButton(
onPressed: _testError,
tooltip: 'Error',
child: const Icon(Icons.warning),
),
],
),
);
}
}
安装
该插件的已发布版本可以在 pub.dev 上找到。
图片缓存
ImageFade
兼容 CachedNetworkImageProvider
。
更多信息
更多关于 ImageFade
的信息和示例,请参考其 GitHub仓库。
更多关于Flutter图片渐变效果插件image_fade的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图片渐变效果插件image_fade的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用image_fade
插件来实现图片渐变效果的代码示例。
首先,确保你已经在pubspec.yaml
文件中添加了image_fade
依赖项:
dependencies:
flutter:
sdk: flutter
image_fade: ^最新版本号 # 请替换为当前最新版本号
然后,运行flutter pub get
来安装依赖项。
以下是一个简单的示例代码,展示了如何使用image_fade
插件:
import 'package:flutter/material.dart';
import 'package:image_fade/image_fade.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ImageFadeExample(),
);
}
}
class ImageFadeExample extends StatefulWidget {
@override
_ImageFadeExampleState createState() => _ImageFadeExampleState();
}
class _ImageFadeExampleState extends State<ImageFadeExample> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Fade Example'),
),
body: Center(
child: FadeTransitionImage(
image: NetworkImage('https://example.com/image1.jpg'), // 替换为你的图片URL
placeholder: NetworkImage('https://example.com/image2.jpg'), // 替换为你的占位图片URL
fadeFraction: _animation.value,
),
),
);
}
}
class FadeTransitionImage extends StatelessWidget {
final ImageProvider image;
final ImageProvider placeholder;
final double fadeFraction;
const FadeTransitionImage({
Key? key,
required this.image,
required this.placeholder,
required this.fadeFraction,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.center,
children: <Widget>[
Opacity(
opacity: fadeFraction,
child: Image(
image: placeholder,
fit: BoxFit.cover,
),
),
Opacity(
opacity: 1 - fadeFraction,
child: Image(
image: image,
fit: BoxFit.cover,
),
),
],
);
}
}
注意:
image_fade
插件本身并没有直接提供一个现成的FadeTransitionImage
组件,上面的代码实现了一个自定义的FadeTransitionImage
组件来模拟渐变效果。- 在上面的代码中,
FadeTransitionImage
组件通过Opacity
组件和Stack
组件来实现两张图片的渐变过渡效果。 - 使用了
AnimationController
来控制渐变效果的动画,并设置了一个重复的动画,使得图片在两张图片之间不断渐变。
你可以根据实际需要调整动画的持续时间、曲线以及图片URL等参数。希望这个示例对你有帮助!