본문 바로가기
[Flutter]

[Flutter] Widget / 위젯 - 애니메이션

by Hevton 2021. 9. 4.
반응형

 

애니메이션

 

Hero

Hero 위젯은 화면 전환시 자연스럽게 연결되는 애니메이션을 지원한다.

// MaterialApp을 선언하지 않은 클래스에서
body: Center(
        child: GestureDetector(
          onTap: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => HeroDetailPage()),
            );
          },
          child: Hero(
            tag: 'image',
            child: Image.asset(
              'assets/sample.jpg',
              width: 100,
              height: 100,
            ),
          ),
        ),
      )
      
      
      
      
class HeroDetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Hero Detail'),
      ),
      body: Hero(
        tag: 'image',
        child: Image.asset('assets/sample.jpg'),
      ),
    );
  }
}

클릭시 자연스럽게 커지며 화면이 전환되는 효과가 발생한다.

주의할 점은 tag 부분의 이름이 두 위젯에서 같아야 한다는 것.

 

+ 오류가 발생한다면 여기 글을 참고하면 해결될 것이다.

 


 

 

AnimatedContainer

Hero 위젯이 화면 전환시 애니메이션 효과를 지원했다면,

AnimatedContainer 위젯은 한 화면 내에서 setState() 함수를 호출하여 화면을 새로 그릴 때 변경된 프로퍼티에 의해 애니메이션 되도록 해준다.

한마디로, 현재 화면에서 애니메이션을 주면서 크기나 모양을 변경시킬 때 사용한다.

 

import 'dart:math'; // Random 클래스 사용을 위해




// StatefulWidget 내부

double _size = 100.0;

body: Center(
        child: GestureDetector(
          onTap: () {
            final random = Random(); // Random 클래스 사용 준비
            setState(() {
              // 클릭할 때 마다 100.0 ~ 299.0 사이의 실수를 랜덤하게 얻기
              _size = random.nextInt(200).toDouble() + 100;
            });
          },
          child: AnimatedContainer(
            duration: Duration(seconds: 1), // Duration은 필수설정.
            width: _size,
            height: _size,
            child: Image.asset('assets/sample.jpg'),
            curve: Curves.fastOutSlowIn, // Curves 클래스에는 미리 정의된 여러 애니메이션 효과들이 있다.
          ),
        ),
      )

 

누를때마다 크기가 변한다

nextInt(200) : 0 ~ 199 사이의 난수를 정수로 반환

toDouble() : 정수를 실수로 변환

+100 : 100씩 더함

AnimatedContainer의 width, height 프로퍼티가 double을 받기에 double로 변경한 것.

 

 

<애니메이션 원리>

setState() 함수에 의해 다시 그려질 때, AnimatedContainer 위젯은 이전 _size 값에서 새로 갱신된 _size값까지 애니메이션된다.

 


 

SliverAppBar와 SliverFillRemaining

둘은 화면 헤더를 동적으로 표현하는 위젯이다.

위로 스크롤하면 헤더 부분이 작아지면서 헤더 하단에 있던 정적인 내용만 보이는 AppBar 형태로 애니메이션된다.

이런 효과를 Sliver 효과라고 부른다.

 

Scaffold에서 appBar를 지정하지 않는다는 것을 주의한다.

body에 CustomScrollView의 인스턴스를 지정하고

CustomScrollView의 slivers 프로퍼티에 SliverAppBarSliverFillRemaining 위젯을 설정한다.

body: CustomScrollView(
          slivers: <Widget> [
            SliverAppBar( // 헤더 영역
              pinned: true, // 축소시 상단에 AppBar가 고정되는지 사라지는지 설정
              expandedHeight: 180.0, // 헤더의 최대 높이. 확대될 때의 최대 높이.
              flexibleSpace: FlexibleSpaceBar( // 늘어나는 영역의 UI 정의(확대/축소되는 영역UI)
                title: Text('Sliver'),
                background: Image.asset(
                  'assets/sample.jpg',
                  fit: BoxFit.cover,
                ),
              ),
            ),
            SliverFillRemaining( // 내용 영역
              child: Center(
                child: Text('center'),
              ),
            ),
          ],
        )

 

 


 

SliverAppBar와 SliverList

앞선 SliverFillRemaining 위젯은 하나의 정적인 화면을 구성할 때 사용하는 반면,

다음 그림처럼 ListView를 사용하여 Sliver 효과를 주고 싶다면 ListView 대신 SliverList를 사용해야 한다.

 

위 코드와 다 동일하고 SliverFillRemaining 부분만 SliverList로 변경한 것이다.

  // No. 0 ~ No. 49
  final _items = List.generate(50, (i) => ListTile(title: Text('No. $i')));
  
  
  body: CustomScrollView(
          slivers: <Widget> [
            SliverAppBar( // 헤더 영역
              pinned: true, // 축소시 상단에 AppBar가 고정되는지 설정
              expandedHeight: 180.0, // 헤더의 최대 높이
              flexibleSpace: FlexibleSpaceBar( // 늘어나는 영역의 UI 정의
                title: Text('Sliver'),
                background: Image.asset(
                  'assets/sample.jpg',
                  fit: BoxFit.cover,
                ),
              ),
            ),
            SliverList( // 내용 영역
              delegate: SliverChildListDelegate(_items),
            ),
          ],
        )

 


 

 

서적 : 오준석의 플러터 생존코딩

반응형