[Flutter] 애니메이션

2023-03-18 hit count image

이번 블로그 포스트에서는 Flutter에서 간단한 애니메이션을 사용하기 위해 AnimatedContainer와 AnimatedOpacity를 사용하는 방법에 대해서 알아봅시다.

개요

Flutter에서 간단한 애니메이션을 사용하기 위해 AnimatedContainer 위젯과 AnimatedOpacity 위젯을 사용하는 방법에 대해서 살펴보도록 하겠습니다.

이 블로그 포스트에서 소개하는 소스 코드는 아래에 링크에서 확인할 수 있습니다.

Flutter 프로젝트 생성

Flutter에서 간단한 애니메이션을 사용법을 확인하기 위해, 다음 명령어를 사용하여 새로운 Flutter 프로젝트를 생성합니다.

flutter create my_app
cd my_app

AnimatedContainer

프로젝트를 생성하였다면, main.dart 파일을 다음과 같이 수정하여 AnimatedContainer 위젯을 표시합니다.

import 'dart:math';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  double _width = 0;
  double _height = 0;
  Color _color = Colors.green;
  double _borderRadious = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AnimatedContainer'),
      ),
      body: Center(
        child: AnimatedContainer(
          duration: Duration(seconds: 1),
          curve: Curves.fastOutSlowIn,
          width: _width,
          height: _height,
          decoration: BoxDecoration(
              color: _color,
              borderRadius: BorderRadius.circular(_borderRadious)),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            final random = Random();
            _width = random.nextInt(300).toDouble();
            _height = random.nextInt(300).toDouble();
            _color = Color.fromRGBO(random.nextInt(256), random.nextInt(256),
                random.nextInt(256), 1);
            _borderRadious = random.nextInt(150).toDouble();
          });
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}

위와 같이 코드를 작성하면 다음과 같은 화면을 확인할 수 있습니다.

Flutter - AnimatedContainer

그럼 AnimatedContainer 위젯을 사용하는 부분만 자세히 살펴보도록 하겠습니다.

class _MyHomePageState extends State<MyHomePage> {
  double _width = 0;
  double _height = 0;
  Color _color = Colors.green;
  double _borderRadious = 0;
  ...
}

Statefull widget을 사용하여 애니메이션에 사용될 변수들을 정의하였습니다.

class _MyHomePageState extends State<MyHomePage> {
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      body: Center(
        child: AnimatedContainer(
          duration: Duration(seconds: 1),
          curve: Curves.fastOutSlowIn,
          width: _width,
          height: _height,
          decoration: BoxDecoration(
              color: _color,
              borderRadius: BorderRadius.circular(_borderRadious)),
        ),
      ),
      ...
    );
  }
}

이렇게 정의한 변수들을 AnimatedContainer 위젯을 생성할 때 전달하였습니다.

class _MyHomePageState extends State<MyHomePage> {
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            final random = Random();
            _width = random.nextInt(300).toDouble();
            _height = random.nextInt(300).toDouble();
            _color = Color.fromRGBO(random.nextInt(256), random.nextInt(256),
                random.nextInt(256), 1);
            _borderRadious = random.nextInt(150).toDouble();
          });
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}

마지막으로 FloatingActionButton을 선택하였을 때, setState를 통해 애니메이션에서 사용되는 변수들의 값을 변경해 주었습니다. 이제 FloatingActionButton 버튼을 누르면 다양한 모양의 사각형이 화면에 표시되는 것을 확인할 수 있습니다.

AnimatedOpacity

AnimatedOpacity 위젯은 AnimatedContainer 위젯과는 다르게, 단순히 투명도(Opacity)에 대한 애니메이션을 적용할 수 있습니다. main.dart 파일을 열고 다음과 같이 수정합니다.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _isVisible = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AnimatedOpacity'),
      ),
      body: Center(
        child: AnimatedOpacity(
          opacity: _isVisible ? 1.0 : 0,
          duration: Duration(seconds: 1),
          child: Container(
            width: 200,
            height: 200,
            color: Colors.green,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _isVisible = !_isVisible;
          });
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}

위와 같이 코드를 작성하면 다음과 같은 화면을 확인할 수 있습니다.

Flutter - AnimatedOpacity

그럼 AnimatedOpacity 위젯을 사용하는 부분만 자세히 살펴보도록 하겠습니다.

class _MyHomePageState extends State<MyHomePage> {
  bool _isVisible = true;
  ...
}

이번 예제에서는 _isVisible 변수를 사용하여, true인 경우에는 AnimatedOpacity 위젯이 화면에 표시되도록 하고, false인 경우 위젯이 화면에 표시되지 않도록 할 예정입니다.

class _MyHomePageState extends State<MyHomePage> {
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      body: Center(
        child: AnimatedOpacity(
          opacity: _isVisible ? 1.0 : 0,
          duration: Duration(seconds: 1),
          child: Container(
            width: 200,
            height: 200,
            color: Colors.green,
          ),
        ),
      ),
      ...
    );
  }
}

AnimatedOpacity 위젯은 child로 위젯을 필수로 전달해야 하며, opacity에 원하는 값을 전달함으로써 투명도에 애니메이션을 적용할 수 있습니다.

class _MyHomePageState extends State<MyHomePage> {
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _isVisible = !_isVisible;
          });
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}

이제 FloatingActionButton 위젯을 통해 _isVisible을 변경하여, AnimatedOpacity 위젯의 투명도를 변경하였습니다.

완료

이것으로 Flutter에서 AnimatedContainer 위젯과 AnimatedOpacity 위젯을 통해 간단하게 애니메이션을 적용하는 방법에 대해서 살펴보았습니다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

앱 홍보

책 홍보

블로그를 운영하면서 좋은 기회가 생겨 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
[심통]현장에서 바로 써먹는 리액트 with 타입스크립트 : 리액트와 스토리북으로 배우는 컴포넌트 주도 개발, 심통
Posts