Never give up

Flutter - AnimatedBuilder with transition 본문

Flutter

Flutter - AnimatedBuilder with transition

대기만성 개발자 2020. 8. 3. 16:17
반응형

화면을 구성하다보면 Navigator를 통하여 다른 화면으로 이동해야되는 상황이 생기고

Animation을 이용하여 조금 더 멋진 화면을 구성하는데

listener안에서 setState를 이용하면 성능이 떨어지기 때문에

AnimatedBuilder를 이용하면 세련된 애니메이션과 성능을 동시에 잡을 수 있습니다

 

메인화면

class TestAnimation extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Animation test')),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 80),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            RaisedButton(
                child: Text('Fade transition'),
                onPressed: () => Navigator.push(context,
                    MaterialPageRoute(builder: (context) => Screen3()))),
            RaisedButton(
                child: Text('Offset transition'),
                onPressed: () => Navigator.push(context,
                    MaterialPageRoute(builder: (context) => Screen4()))),
          ],
        ),
      ),
    );
  }
}

 

예제 화면 및 위젯

class Screen3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Fade transition')),
        body: Center(child: FadeTransitionWidget(showWidget: TestBox())));
  }
}

class Screen4 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Offset transition')),
        body: Center(child: OffsetTransitionWidget(showWidget: TestBox())));
  }
}

class TestBox extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      width: 200,
      color: Colors.blue,
    );
  }
}

 

Fade를 이용한 Transition

import 'package:flutter/material.dart';

class FadeTransitionWidget extends StatefulWidget {
  final Widget showWidget;

  FadeTransitionWidget({this.showWidget});

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

class _FadeTransitionWidgetState extends State<FadeTransitionWidget>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation _animation;

  @override
  void initState() {
    super.initState();

    _controller =
        AnimationController(duration: Duration(seconds: 1), vsync: this);

    _animation = CurvedAnimation(parent: _controller, curve: Curves.decelerate);

    _controller.forward();
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return FadeTransition(
          opacity: _animation,
          child: widget.showWidget,
        );
      },
    );
  }
}

 

Offset을 이용한 Transition

import 'package:flutter/material.dart';

class OffsetTransitionWidget extends StatefulWidget {
  final Widget showWidget;

  OffsetTransitionWidget({this.showWidget});

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

class _OffsetTransitionWidgetState extends State<OffsetTransitionWidget>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();

    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));

    _controller.forward();
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return Transform.translate(
            offset: Offset(0, -10 * _controller.value),
            child: widget.showWidget);
      },
    );
  }
}

 

AnimatedBuilder를 사용하지 않은 FadeTransition

import 'package:flutter/material.dart';

class FadeWidget extends StatefulWidget {
  final Widget showWidget;

  FadeWidget({this.showWidget});

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

class _FadeWidgetState extends State<FadeWidget>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();

    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));

    _controller.forward();
  }

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

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
        opacity: Tween(begin: 0.0, end: 1.0).animate(
            CurvedAnimation(parent: _controller, curve: Curves.decelerate)),
        child: widget.showWidget);
  }
}

 

AnimatedBuilder를 사용하면 복잡한 위젯트리를 가진곳에서 조금 더 유용하다고 합니다

(공식문서 : https://api.flutter.dev/flutter/widgets/AnimatedBuilder-class.html)

반응형
Comments