본문 바로가기
2023년 부터/Flutter

[Flutter]Animation활용

by JeongUPark 2024. 3. 26.
반응형

앱을 개발하다 보면 사용자 편의성이나 사용성을 위하여 애니메이션을 사용하는 경우가 있는데, 간단한 애니메이션 사용법을 알아 보겠습니다.

Animation 사용방법

flutter에서 animation은 다음과 같은 설정을 통하여 사용할 수 있습니다.

import 'package:flutter/material.dart';

class AnimatedPositionedExample extends StatefulWidget {
  @override
  _AnimatedPositionedExampleState createState() => _AnimatedPositionedExampleState();
}

class _AnimatedPositionedExampleState extends State<AnimatedPositionedExample> with SingleTickerProviderStateMixin {
  AnimationController? _controller;
  Animation<double>? _animation;
  late double _left; // Positioned 위젯의 left 속성을 위한 변수

  @override
  void initState() {
    super.initState();
    _left = 0; // 초기 위치 설정
    _controller = AnimationController(
      duration: const Duration(seconds: 2), // 애니메이션 지속 시간 설정
      vsync: this,
    );

    // Tween을 사용하여 애니메이션 값의 범위를 설정
    _animation = Tween(begin: 0.0, end: 200.0).animate(_controller!)
      ..addListener(() {
        setState(() {
          _left = _animation!.value; // 애니메이션 값에 따라 left 속성 업데이트
        });
      })
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          // 애니메이션이 종료된 시점에 원하는 동작 수행
          print('Animation Completed!');
        }
      });

    _controller!.forward(); // 애니메이션 시작
  }

  @override
  void dispose() {
    _controller!.dispose(); // 컨트롤러 리소스 해제
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Positioned(
            left: _left,
            top: 100,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.blue,
            ),
          ),
        ],
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(home: AnimatedPositionedExample()));
}

 

위와 같은 방법을 사용할 경우 View가 왼쪽 0 지점에서 200까지 움직이는 것을 확인 할 수 있습니다.

 

심화 과정

버튼을 누르거나 사용자 조작에 의해서 다양한 방법으로 애니메이션이 동작해야하는 경우가 있는데,

그러기 위해서는 애니메이션의 시작값과 끝값을 동적으로 변경하여 업데이트 후 AnimationController를 다시 시작해주면 됩니다.

아래 코드는 위에서 설명한 내용을 토대로 작성한 코드 입니다.

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;
  double _start = 0.0;
  double _end = 100.0;

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

    _updateAnimation();
  }

  void _updateAnimation() {
    _animation = Tween(begin: _start, end: _end).animate(_controller)
      ..addListener(() {
        setState(() {});
      })
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          // 애니메이션이 완료된 후 시작점을 업데이트합니다.
          _start = _end;
        }
      });

    _controller
      ..reset() // 컨트롤러를 초기화합니다.
      ..forward(); // 애니메이션을 시작합니다.
  }

  void _moveMore() {
    // 현재 위치에서 40만큼 추가 이동
    _end += 40;
    _updateAnimation();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Expanded(
          child: Transform.translate(
            offset: Offset(_animation.value, 0),
            child: Container(
              width: 100,
              height: 100,
              color: Colors.blue,
            ),
          ),
        ),
        ElevatedButton(
          onPressed: _moveMore,
          child: Text('Move More'),
        ),
      ],
    );
  }
}

 

위에서 중요한 부분은_updateAnimation함수 입니다. 저 함수를 호출 할 때마다 기존 애니메이션은 사라지고 새로운 애니메이션이 동작하기때문입니다.

그래서 위코드를 보면 처음에는 0에서 100까지 움직이다가 버튼을 누를 수록 40만큼 더 움직이게 됩니다. 

반응형