Flutter 動畫封裝

AnimatedWidget

  • AnimatedWidget對addListener和setState進行了封裝使得不需要像之前那樣設置listener以及setStateFlutter動畫,示例如下

import 'package:flutter/material.dart';


class AnimatedLogo extends AnimatedWidget {
  // listenable類似之前寫的addListener,此時可以監聽animation的value
  AnimatedLogo({Key key, Animation<double> animation})
      : super(key: key, listenable: animation);


  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    return Center(
      child: Container(
        margin: EdgeInsets.symmetric(vertical: 10),
        height: animation.value,
        width: animation.value,
        child: FlutterLogo(),
      ),
    );
  }
}


class AnimatedLogoTest extends StatefulWidget {
  @override
  AnimatedLogoTestState createState() => new AnimatedLogoTestState();
}


class AnimatedLogoTestState extends State<AnimatedLogoTest>
    with SingleTickerProviderStateMixin {
  final Duration _duration = const Duration(milliseconds: 3000);
  AnimationController controller;
  Animation<double> animation;


  @override
  build(dynamic ) {
    return new AnimatedLogo(animation: animation);
  }


  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this, duration: _duration);
    animation = Tween(begin: 0.0, end: 300.0).animate(controller);
    controller.forward();
  }


  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    controller.dispose();
  }
}

AnimatedBuilder

  • 我們想讓Container中的寬高與animation分離,寬高大小完全由動畫去管理,Container只做自己的顯示,此時我們需要藉助AnimatedBuilder來實現
AnimatedBuilder特點
  • 繼承於AnimatedWidget,可以直接當作組件來使用,不需要顯示添加addListener(), 以及並不需要顯示調用setState()
  • 只調用動畫組件中的build,在複雜佈局下性能有所提高

eg:


class AnimatedLogoTest extends StatefulWidget {
  @override
  AnimatedLogoTestState createState() => new AnimatedLogoTestState();
}


class AnimatedLogoTestState extends State<AnimatedLogoTest>
    with SingleTickerProviderStateMixin {
  final Duration _duration = const Duration(milliseconds: 3000);
  AnimationController controller;
  Animation<double> animation;


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return AnimatedBuilder(
      animation: animation,
      child: FlutterLogo(),
      builder: (context, child) {
        return Transform.rotate(angle: animation.value,
          child: child,);
      },
    );
  }


  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this, duration: _duration);
    animation = Tween(begin: 0.0, end: 2 * pi).animate(controller);
    controller.forward();
  }


  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    controller.dispose();
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章