2017-08-16 1 views
1

Ich versuche, eine Animation in einem CustomPainter zu erstellen, in dem die Animation von unten nach oben beginnt, aber es beginnt an der Spitze.Flattern - Animation von unten nach oben in CustomPainter

Wenn Sie auf die FloatActionButton klicken, sollte das Rechteck auf die maximale Höhe des Bildschirms steigen, und wenn Sie erneut tippen, gehen Sie zurück auf die Mindestgröße.

Ich kann die Größe des Bildschirms bekommen, aber ich bin nicht in der Lage, diese Animation von unten nach oben einzufügen. kannst du mir helfen?

enter image description here

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

void main() { 
    runApp(new MaterialApp(home: new HomePage())); 
} 

class HomePage extends StatefulWidget { 
    @override 
    HomePageState createState() => new HomePageState(); 
} 

class HomePageState extends State<HomePage> with TickerProviderStateMixin { 
    AnimationController _controller; 
    Animation<double> _animation; 
    bool upDown = true; 

    @override 
    void initState() { 
    _controller = new AnimationController(
     vsync: this, 
     duration: const Duration(milliseconds: 180), 
    ); 

    _animation = new CurvedAnimation(
     parent: _controller, 
     curve: new Interval(0.0, 1.0, curve: Curves.linear), 
    ); 
    } 

    @override 
    Widget build(BuildContext context) { 
    final ui.Size logicalSize = MediaQuery.of(context).size; 
    final double _width = logicalSize.width; 
    final double _height = logicalSize.height; 

    void _up(){ 
     setState((){ 
     if(upDown) { 
      upDown = false; 
      _controller.forward(from: 0.0); 
     } else { 
      upDown = true; 
      _controller.reverse(from: 1.0); 
     } 
     }); 
    } 

    return new Scaffold(
     body: new Stack(
      children: <Widget>[ 
       new Positioned(
        bottom: 0.0, 
        child: new AnimatedBuilder(
        animation: _animation, 
        builder: (BuildContext context, Widget child) { 
        return new Container(
         height: _height, 
         child: new CustomPaint(
         painter: new Sky(_width, _height * _animation.value), 
         //child: new Text('$_height '+ _animation.value.toString()), 
        ), 
        ); 
        }, 
       ), 
      ), 
       new Positioned(
       bottom: 16.0, 
       right: 16.0, 
       child: new FloatingActionButton(
        backgroundColor: new Color(0xFFE57373), 
        child: new Icon(Icons.add), 
        onPressed:(){ 
        _up(); 
        }, 
       ) 
      ) 
      ] 
     ) 
    ); 
    } 
} 

class Sky extends CustomPainter { 
    final double _width; 
    double _rectHeight; 

    Sky(this._width, this._rectHeight); 

    @override 
    void paint(Canvas canvas, Size size) { 
    canvas.drawRect(
     new Rect.fromLTRB(
      0.0, 0.0, this._width, _rectHeight 
    ), 
     new Paint()..color = new Color(0xFF0099FF), 
    ); 
    } 

    @override 
    bool shouldRepaint(Sky oldDelegate) { 
    return _width != oldDelegate._width || _rectHeight != oldDelegate._rectHeight; 
    } 
} 

Antwort

2

können Sie einen AnimatedBuilder, dies zu tun. Stellen Sie außerdem sicher, dass Sie eine funktionierende Implementierung von shouldRepaint bereitstellen. Ihre upDown Mitgliedsvariable sollte ein Mitglied der State und nicht Teil der build-Funktion sein.

screenshot

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

void main() { 
    runApp(new MaterialApp(home: new HomePage())); 
} 

class HomePage extends StatefulWidget { 
    @override 
    HomePageState createState() => new HomePageState(); 
} 

class HomePageState extends State<HomePage> with TickerProviderStateMixin { 
    AnimationController _controller; 
    Animation<double> _animation; 
    bool upDown = true; 

    @override 
    void initState() { 
    _controller = new AnimationController(
     vsync: this, 
     duration: const Duration(milliseconds: 180), 
    ); 

    _animation = new CurvedAnimation(
     parent: _controller, 
     curve: new Interval(0.0, 1.0, curve: Curves.linear), 
    ); 
    } 

    @override 
    Widget build(BuildContext context) { 
    final ui.Size logicalSize = MediaQuery.of(context).size; 
    final double _width = logicalSize.width; 
    final double _height = logicalSize.height; 

    void _up(){ 
     setState((){ 
     if(upDown) { 
      upDown = false; 
      _controller.forward(from: 0.0); 
     } else { 
      upDown = true; 
      _controller.reverse(from: 1.0); 
     } 
     }); 
    } 

    return new Scaffold(
     body: new Stack(
      children: <Widget>[ 
       new Positioned(
        bottom: 0.0, 
        child: new AnimatedBuilder(
        animation: _animation, 
        builder: (BuildContext context, Widget child) { 
        return new Container(
         height: _height, 
         child: new CustomPaint(
         painter: new Sky(_width, _height * _animation.value), 
        ), 
        ); 
        }, 
       ), 
      ), 
       new Positioned(
       bottom: 16.0, 
       right: 16.0, 
       child: new FloatingActionButton(
        backgroundColor: new Color(0xFFE57373), 
        child: new Icon(Icons.add), 
        onPressed:(){ 
        _up(); 
        }, 
       ) 
      ) 
      ] 
     ) 
    ); 
    } 
} 

class Sky extends CustomPainter { 
    final double _width; 
    double _rectHeight; 

    Sky(this._width, this._rectHeight); 

    @override 
    void paint(Canvas canvas, Size size) { 
    canvas.drawRect(
     new Rect.fromLTRB(
      0.0, size.height - _rectHeight, this._width, size.height 
    ), 
     new Paint()..color = new Color(0xFF0099FF), 
    ); 
    } 

    @override 
    bool shouldRepaint(Sky oldDelegate) { 
    return _width != oldDelegate._width || _rectHeight != oldDelegate._rectHeight; 
    } 
} 
+0

Danke für die Hilfe, für die gif der blaue Animation von oben beginnt nach unten, wie die Animation der blauen von unten nach oben beginnen? – rafaelcb21

+0

Ich habe Ihren Code ein wenig geändert und die Frage neu geschrieben, seit ich versucht habe, in einer Reihe von Teilen des Codes zu spielen, und ich kann die Animation im unteren – rafaelcb21

+1

nicht starten Ich bearbeitete meine Antwort, die Sie gerade benötigten Um den 'drawRect' Aufruf in' new Rect.fromLTRB zu ändern (0.0, size.height - _rectHeight, this._width, size.height) ' –

Verwandte Themen