Flutter图片交叉淡入淡出动画插件cross_fade的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter图片交叉淡入淡出动画插件cross_fade的使用

简介

cross_fade 是一个Flutter包,它提供了一个灵活且易于使用的交叉淡入淡出动画效果。与官方的 AnimatedCrossFade 相比,它更加灵活,并且可以处理不同大小的Widget之间的动画过渡。

cross_fade_example_1 cross_fade_example_2

此外,CrossFade 还可以处理不同大小的Widget之间的动画过渡:

cross_fade_example_3

因此,CrossFade 可以被包裹在任何组件中,并且会动画化其大小变化。

安装

在你的 pubspec.yaml 文件中添加依赖:

dependencies:
  cross_fade: ^latest_version

请将 latest_version 替换为 pub.dev 上提供的最新版本号。

使用方法

基本用法

下面是一个简单的例子,展示了如何使用 CrossFade 来创建一个交叉淡入淡出的文本动画:

CrossFade<int>(
  value: value,
  builder: (context, i) => Text('$i'),
)

示例代码

以下是一个完整的示例代码,演示了如何使用 cross_fade 包来实现多个Widget之间的交叉淡入淡出动画效果:

import 'dart:async';

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'CrossFade Example',
      home: MyHomePage(title: 'CrossFade Example Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List _objects = const [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  final List<Widget> _icons = const [
    Icon(
      Icons.cancel,
      size: 150.0,
    ),
    Icon(
      Icons.check_circle,
      size: 150.0,
    ),
    Icon(
      Icons.camera_rounded,
      size: 150.0,
    ),
  ];
  final List<Widget> _widgets = [
    Container(
      color: Colors.blue,
      width: 150.0,
      height: 150.0,
      child: const Center(child: Text('Any widget')),
    ),
    Container(
      color: Colors.red,
      height: 100.0,
      width: 200,
      child: const Center(child: Text('Any other widget')),
    ),
    Container(
      color: Colors.green,
      height: 50.0,
      width: 300.0,
      child: const Center(child: Text('Any other other widget')),
    ),
  ];
  int _index = 0;
  late final Timer _timer;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(
        const Duration(milliseconds: 1500), (t) => setState(() => _index++));
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Center(
            child: Container(
              color: Colors.red,
              child: CrossFade(
                value: _objects[_index % _objects.length],
                builder: (context, i) => Text(
                  '$i',
                  style: theme.textTheme.displayLarge,
                  textAlign: TextAlign.center,
                ),
              ),
            ),
          ),
          Center(
            child: CrossFade(
              value: _objects[_index % _objects.length],
              builder: (context, i) => Text(
                '$i',
                style: theme.textTheme.displayLarge,
                textAlign: TextAlign.center,
              ),
            ),
          ),
          Center(
            child: DecoratedBox(
              position: DecorationPosition.foreground,
              decoration: BoxDecoration(border: Border.all(width: 3.0)),
              child: CrossFade<int>(
                value: _index,
                builder: (context, i) => _widgets[i % _widgets.length],
              ),
            ),
          ),
          Center(
            child: CrossFade<int>(
              value: _index,
              builder: (context, i) => _icons[i % _icons.length],
            ),
          ),
          Center(
            child: CrossFade(
              value: _objects[_index % _objects.length],
              builder: (context, i) => Text(
                '$i',
                style: theme.textTheme.displayLarge,
                textAlign: TextAlign.center,
              ),
              highlightTransition: (o1, o2) => true,
            ),
          ),
        ],
      ),
    );
  }
}

在这个示例中,我们创建了一个定时器,每1.5秒更新一次 _index 的值,从而触发 CrossFade 的动画效果。通过这种方式,你可以看到不同的图标和容器之间的交叉淡入淡出动画。

参数说明

  • value: 动画的当前值。
  • builder: 根据当前值构建Widget的回调函数。
  • highlightTransition: 可选参数,用于控制是否高亮过渡效果,默认为 false

如果你喜欢这个包,请在 pub.devGitHub 上点赞和支持开发者的工作!


更多关于Flutter图片交叉淡入淡出动画插件cross_fade的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片交叉淡入淡出动画插件cross_fade的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个使用 cross_fade 插件在 Flutter 中实现图片交叉淡入淡出动画的示例代码。cross_fade 插件允许你在两个 Widget 之间创建平滑的过渡动画,这在图片切换时非常有用。

首先,确保你已经在 pubspec.yaml 文件中添加了 cross_fade 依赖:

dependencies:
  flutter:
    sdk: flutter
  cross_fade: ^2.0.0  # 请检查最新版本号

然后运行 flutter pub get 来获取依赖。

接下来是示例代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Cross Fade Image Animation'),
        ),
        body: Center(
          child: CrossFadeImageExample(),
        ),
      ),
    );
  }
}

class CrossFadeImageExample extends StatefulWidget {
  @override
  _CrossFadeImageExampleState createState() => _CrossFadeImageExampleState();
}

class _CrossFadeImageExampleState extends State<CrossFadeImageExample> with SingleTickerProviderStateMixin {
  bool isFirstImage = true;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        CrossFade(
          // CrossFade widget
          firstChild: Image.network(
            'https://via.placeholder.com/300x200?text=Image+1',
            fit: BoxFit.cover,
          ),
          secondChild: Image.network(
            'https://via.placeholder.com/300x200?text=Image+2',
            fit: BoxFit.cover,
          ),
          // Duration for the cross fade animation
          crossFadeState: isFirstImage ? CrossFadeState.showFirst : CrossFadeState.showSecond,
          duration: Duration(seconds: 1), // Animation duration
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () {
            setState(() {
              isFirstImage = !isFirstImage;
            });
          },
          child: Text(isFirstImage ? 'Show Second Image' : 'Show First Image'),
        ),
      ],
    );
  }
}

代码解释:

  1. 依赖引入

    • pubspec.yaml 中引入 cross_fade 插件。
  2. 主应用

    • MyApp 类创建了一个简单的 MaterialApp,其中包含一个 Scaffold 和一个 Center,用于居中对齐内容。
  3. CrossFadeImageExample

    • CrossFadeImageExample 是一个 StatefulWidget,用于管理图片切换的状态。
  4. _CrossFadeImageExampleState

    • isFirstImage 是一个布尔值,用于跟踪当前显示的是哪张图片。
    • CrossFade 小部件接受两个子 Widget(firstChildsecondChild),这些子 Widget 是我们要淡入淡出的图片。
    • crossFadeState 属性决定了当前显示哪个子 Widget。我们使用 isFirstImage 的值来设置这个属性。
    • duration 属性设置了动画的持续时间。
    • 一个 ElevatedButton 用于切换图片。点击按钮时,会调用 setState 方法来更新 isFirstImage 的值,从而触发重建并触发动画。

运行这个示例代码,你会看到一个按钮和一张图片。点击按钮时,图片会在两张之间平滑地淡入淡出切换。

回到顶部