[flutter] 플러터(IndexedStack)에서 인덱스가 변경될 때 애니메이션을 추가하는 방법은 무엇인가요?

먼저, IndexedStack 위젯을 사용할 화면을 구현하고 애니메이션 효과를 주고자 하는 위젯을 만듭니다. 예를 들어, 애니메이션이 적용된 컨테이너를 보여주는 AnimatedContainer 위젯을 사용하겠습니다.

import 'package:flutter/material.dart';

class AnimatedContent extends StatelessWidget {
  final bool isActive;
  final Widget child;

  AnimatedContent({this.isActive, this.child});

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: Duration(milliseconds: 500),
      curve: Curves.easeInOut,
      width: isActive ? 200.0 : 0.0,
      height: isActive ? 200.0 : 0.0,
      child: child,
    );
  }
}

위의 코드는 isActive 변수에 따라서 컨테이너의 크기가 변경되는 AnimatedContainer 위젯을 정의한 것입니다.

이제, IndexedStack 위젯에서 인덱스가 변경될 때 애니메이션 효과를 주기 위해 애니메이션 컨트롤러와 애니메이션을 설정해야 합니다. 아래의 코드는 IndexedStack 위젯에 애니메이션 기능을 추가한 예시입니다.

import 'package:flutter/material.dart';

class AnimatedIndexedStack extends StatefulWidget {
  final List<Widget> children;

  AnimatedIndexedStack({this.children});

  @override
  _AnimatedIndexedStackState createState() => _AnimatedIndexedStackState();
}

class _AnimatedIndexedStackState extends State<AnimatedIndexedStack> with SingleTickerProviderStateMixin {
  int currentIndex = 0;
  AnimationController _controller;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    _animation = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
  }

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

  void changeIndex(int index) {
    setState(() {
      currentIndex = index;
    });
    _controller.reverse(from: 1.0); // 애니메이션 역재생
    _controller.forward(); // 애니메이션 재생
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        int nextIndex = (currentIndex + 1) % widget.children.length;
        changeIndex(nextIndex);
      },
      child: IndexedStack(
        index: currentIndex,
        children: widget.children.map((child) => AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
            return Opacity(
              opacity: _animation.value,
              child: Transform.scale(
                scale: _animation.value,
                child: child,
              ),
            );
          },
          child: child,
        )).toList(),
      ),
    );
  }
}

위의 코드는 AnimatedIndexedStack이라는 새로운 StatefulWidget을 만들었으며, IndexedStack 위젯을 사용하여 여러 개의 위젯을 겹쳐서 보여주고, 애니메이션 효과를 주기 위해 GestureDetector와 AnimationController, Animation을 사용하였습니다.

이제 위젯을 사용할 곳에서 AnimatedIndexedStack을 사용하면 인덱스가 변경될 때 애니메이션 효과가 적용된 것을 확인할 수 있습니다.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Animated IndexedStack'),
        ),
        body: Center(
          child: AnimatedIndexedStack(
            children: [
              Container(
                color: Colors.red,
                child: Center(child: Text('Widget 1')),
              ),
              Container(
                color: Colors.green,
                child: Center(child: Text('Widget 2')),
              ),
              Container(
                color: Colors.blue,
                child: Center(child: Text('Widget 3')),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

위의 코드는 앞서 만든 AnimatedIndexedStack을 사용하여 세 개의 컨테이너 위젯을 인덱스가 변경될 때 애니메이션 효과와 함께 보여주는 예시입니다.

애니메이션을 적용할 위젯과 애니메이션 효과의 속도 및 방식은 개발자에게 따라 다를 수 있으며, 필요에 따라서 코드를 수정하여 원하는 애니메이션 효과를 구현할 수 있습니다.

더 많은 정보를 원하시면 Flutter 애니메이션 가이드를 참고해주세요.