Flutter进阶动画技巧教程

Flutter进阶动画技巧教程

3 回复

抱歉,我还没到那个level。作为屌丝程序猿,还在努力学习基础呢~

更多关于Flutter进阶动画技巧教程的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


建议多动手实践,掌握AnimationController、Tween等核心类的使用,学会配合Builder和Listener优化动画效果。

Flutter 提供了强大的动画支持,以下是一些进阶动画技巧,帮助你创建更复杂和流畅的用户体验。

1. 使用 AnimatedBuilderAnimationController

AnimatedBuilder 是一个非常有用的 widget,它允许你在动画过程中重建部分 UI,而不需要重建整个 widget 树。结合 AnimationController,你可以精确控制动画的播放。

class MyAnimatedWidget extends StatefulWidget {
  @override
  _MyAnimatedWidgetState createState() => _MyAnimatedWidgetState();
}

class _MyAnimatedWidgetState extends State<MyAnimatedWidget> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);
    _animation = Tween<double>(begin: 0, end: 1).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return Opacity(
          opacity: _animation.value,
          child: child,
        );
      },
      child: FlutterLogo(size: 100),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

2. 使用 Hero 动画

Hero 动画用于在不同页面之间共享元素,创建平滑的过渡效果。只需在两个页面的相同元素上使用相同的 tag

// Page 1
Hero(
  tag: 'hero-tag',
  child: FlutterLogo(size: 100),
);

// Page 2
Hero(
  tag: 'hero-tag',
  child: FlutterLogo(size: 200),
);

3. 使用 CustomPainterCanvas 绘制自定义动画

CustomPainter 允许你使用 Canvas 绘制自定义图形和动画。你可以通过重写 paint 方法来实现复杂的动画效果。

class MyCustomPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;

    canvas.drawCircle(Offset(size.width / 2, size.height / 2), 50, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

class MyAnimatedPainter extends StatefulWidget {
  @override
  _MyAnimatedPainterState createState() => _MyAnimatedPainterState();
}

class _MyAnimatedPainterState extends State<MyAnimatedPainter> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat();
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: MyCustomPainter(),
      size: Size(200, 200),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

4. 使用 TweenSequenceCurvedAnimation

TweenSequence 允许你定义一系列 Tween,并在动画过程中依次应用它们。CurvedAnimation 则允许你使用曲线来控制动画的速度。

Animation<double> _animation;

@override
void initState() {
  super.initState();
  _controller = AnimationController(
    duration: const Duration(seconds: 2),
    vsync: this,
  )..repeat();

  _animation = TweenSequence<double>(
    <TweenSequenceItem<double>>[
      TweenSequenceItem<double>(
        tween: Tween<double>(begin: 0, end: 1),
        weight: 50,
      ),
      TweenSequenceItem<double>(
        tween: Tween<double>(begin: 1, end: 0),
        weight: 50,
      ),
    ],
  ).animate(CurvedAnimation(
    parent: _controller,
    curve: Curves.easeInOut,
  ));
}

5. 使用 AnimatedListSliverAnimatedList

AnimatedListSliverAnimatedList 允许你在列表中添加或删除项时应用动画效果。

final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
List<String> _items = [];

void _addItem() {
  _items.insert(0, 'Item ${_items.length + 1}');
  _listKey.currentState.insertItem(0);
}

void _removeItem(int index) {
  final item = _items.removeAt(index);
  _listKey.currentState.removeItem(index, (context, animation) {
    return SizeTransition(
      sizeFactor: animation,
      child: ListTile(title: Text(item)),
    );
  });
}

@override
Widget build(BuildContext context) {
  return Column(
    children: [
      ElevatedButton(
        onPressed: _addItem,
        child: Text('Add Item'),
      ),
      Expanded(
        child: AnimatedList(
          key: _listKey,
          initialItemCount: _items.length,
          itemBuilder: (context, index, animation) {
            return SizeTransition(
              sizeFactor: animation,
              child: ListTile(
                title: Text(_items[index]),
                onTap: () => _removeItem(index),
              ),
            );
          },
        ),
      ),
    ],
  );
}

这些技巧可以帮助你在 Flutter 中创建更复杂和吸引人的动画效果。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!