2017-09-28 4 views
1

Flutter에서 시작하여 계속 페이드 인 및 페이드 아웃하면서 회전하는 애니메이션을 만들려고합니다. 지금까지 순환은 작동하지만 페이딩 효과로 인해 어려움을 겪고 있습니다. 위젯은 점차 투명 해지지만 한 번 회전 한 직후 다시 투명하게 바뀌기 전에 다시 불투명으로 이동합니다. 이 문제를 해결하기 위해 노력하고 있지만 어떻게 찾을 수없는 것 같습니다. .forward().reverse()을 사용하면 작동하지 않겠지 만 불투명 한 애니메이션을 잘못 구현했을 수 있습니다. 코드의 큰 덩어리 죄송Flutter 애니메이션 점점 페이드 인/아웃하는 법

class AnimatedLoader extends AnimatedWidget { 
    static final _opacityTween = new Tween<double>(begin: 1.0, end: 0.3); 

    AnimatedLoader({ 
    Key key, 
    this.alignment: FractionalOffset.center, 
    Animation<double> turns, 
    Animation<double> animation, 
    this.child, 
    }) : super(key: key, listenable: turns); 

    Animation<double> get turns => listenable; 

    final FractionalOffset alignment; 
    final Widget child; 

    @override 
    Widget build(BuildContext context) { 
    final Animation<double> animation = listenable; 
    final double turnsValue = turns.value; 
    final Matrix4 transform = new Matrix4.rotationZ(turnsValue * math.PI * 2.0); 
    return new Transform(
     alignment: alignment, 
     transform: transform, 
     child: new Opacity(
     opacity: _opacityTween.evaluate(animation), 
     child: child, 
    ) 
    ); 
    } 
} 

class AppLoader extends StatefulWidget { 
    AppLoaderState createState() => new AppLoaderState(); 
} 

class AppLoaderState extends State<AppLoader> with TickerProviderStateMixin { 
    AnimationController _controller; 
    AnimationController _controllerOp; 
    Animation<double> animation; 

    @override initState(){ 
    super.initState(); 
    _controller = new AnimationController(
     duration: const Duration(milliseconds: 1500), 
     vsync: this, 
    )..repeat(); 

    _controllerOp = new AnimationController(
     duration: const Duration(milliseconds: 800), 
     vsync: this, 
    ); 
    animation = new Tween(begin: 0.0, end: 300.0).animate(_controllerOp); 

    animation.addStatusListener((status) { 
     if (status == AnimationStatus.completed) { 
     _controllerOp.reverse(); 
     } else if (status == AnimationStatus.dismissed) { 
     _controllerOp.forward(); 
     } 
    }); 
    _controllerOp.forward(); 
    } 

    @override 
    Widget build(BuildContext context) { 
    return new Center (
     child: new AnimatedLoader(
     turns: _controller, 
     alignment: FractionalOffset.center, 
     animation: _controllerOp, 
     child: new Container(
      margin: new EdgeInsets.symmetric(vertical: 10.0), 
      height: 150.0, 
      width: 150.0, 
      child: new FlutterLogo(), 
     ) 
    ), 
    ); 
    } 

, 나는 당신이 올바른 궤도에 있다고 생각

+0

당신은 AnimatedOpacity 대신 불투명도를 사용하여 사용해 볼 수 있습니까? 그냥 생각 :) –

답변

0

. 내가 한 실수를 한 수있는 부분을 확실 해요,하지만 당신은 하나를 사용해야합니다 AnimationController/AnimatedWidget. 귀하의 코드에 몇 가지 버그가 수정되었습니다.

video of pulsing flutter logo

import 'package:flutter/material.dart'; 
import 'dart:math' as math; 

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

class MyApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     home: new MyHomePage(), 
    ); 
    } 
} 

class MyHomePage extends StatelessWidget { 
    Widget build(BuildContext context) { 
    return new Scaffold(
     body: new AppLoader(), 
    ); 
    } 
} 

class PulsateCurve extends Curve { 
    @override 
    double transform(double t) { 
    if (t == 0 || t == 1) 
     return 0.3; 
    return math.sin(t * math.PI) * 0.35 + 0.65; 
    } 
} 

class AnimatedLoader extends AnimatedWidget { 
    static final _opacityTween = new CurveTween(curve: new PulsateCurve()); 

    AnimatedLoader({ 
    Key key, 
    this.alignment: FractionalOffset.center, 
    Animation<double> animation, 
    this.child, 
    }) : super(key: key, listenable: animation); 

    final FractionalOffset alignment; 
    final Widget child; 

    @override 
    Widget build(BuildContext context) { 
    final Animation<double> animation = listenable; 
    final Matrix4 transform = new Matrix4.rotationZ(animation.value * math.PI * 2.0); 
    return new Transform(
     alignment: alignment, 
     transform: transform, 
     child: new Opacity(
      opacity: _opacityTween.evaluate(animation), 
      child: child, 
     ) 
    ); 
    } 
} 

class AppLoader extends StatefulWidget { 
    AppLoaderState createState() => new AppLoaderState(); 
} 

class AppLoaderState extends State<AppLoader> with TickerProviderStateMixin { 
    AnimationController _controller; 

    @override initState() { 
    super.initState(); 
    _controller = new AnimationController(
     duration: const Duration(milliseconds: 1500), 
     vsync: this, 
    )..repeat(); 
    } 

    @override 
    Widget build(BuildContext context) { 
    return new Center (
     child: new AnimatedLoader(
      animation: _controller, 
      alignment: FractionalOffset.center, 
      child: new Container(
      margin: new EdgeInsets.symmetric(vertical: 10.0), 
      height: 150.0, 
      width: 150.0, 
      child: new FlutterLogo(), 
     ) 
    ), 
    ); 
    } 
}