草庐IT

dart - Flutter - CustomPainter 中自下而上的动画

coder 2023-07-22 原文

我正在尝试在 CustomPainter 中创建一个动画,其中动画从底部开始向上,但它是从顶部开始的。

当点击 FloatActionButton 时,矩形应该上升到屏幕的最大高度,当再次点击时返回到最小尺寸。

我可以获取屏幕的大小,但无法从下到上插入此动画。你能帮帮我吗?

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;
  }
}

最佳答案

您可以使用 AnimatedBuilder去做这个。此外,请确保您提供了 shouldRepaint 的有效实现。您的 upDown 成员变量应该是 State 的成员,而不是 build 函数的一部分。

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;
  }
}

关于dart - Flutter - CustomPainter 中自下而上的动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45716127/

有关dart - Flutter - CustomPainter 中自下而上的动画的更多相关文章

  1. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  2. LVGL V8动画 - 2

    动画/*INITIALIZEANANIMATION 初始化一个动画*-----------------------*/lv_anim_ta;lv_anim_init(&a);/*MANDATORYSETTINGS 必选设置*------------------*//*Setthe"animator"function 设置“动画”功能*/lv_anim_set_exec_cb(&a,(lv_anim_exec_xcb_t)lv_obj_set_x);/*Setthe"animator"function*/lv_anim_set_var(&a,obj);/*Lengthoftheanim

  3. Flutter 环境变量配置和flutter doctor中的错误解决 - 2

    一、环境变量右键点击我的电脑-属性:然后找到环境变量 1.Android的SDK不在C盘的话需要额外配这个到用户环境变量:ANDROID_HOMED:\AndroidSDK2.然后在系统变量:Path中添加一条这样的值        D:\Flutter\flutter\bin             这个值写flutter包解压的实际地址即可 3.在系统变量中添加两个镜像变量:        变量名:FLUTTER_STORAGE_BASE_URL      变量值:https://storage.flutter-io.cn        变量名:PUB_HOSTED_URL      变量

  4. ruby - Carrierwave + MiniMagick - 如何将动画 GIF 压缩到第一帧? - 2

    有人知道如何使用Carrierwave+MiniMagick将动画GIF压缩到第一帧吗? 最佳答案 我认为MiniMagick有一些变化,因为我只花了三个小时试图找出为什么Andrey的代码对我不起作用。我收到以下错误:ActiveRecord::RecordInvalid(Validationfailed:ImageFailedtomanipulatewithMiniMagick,maybeitisnotanimage?OriginalError:Command("mogrify-scene/var/folders/0o/0oqN

  5. ruby-on-rails - 如何在 Ajax 请求处理期间显示动画图标 - Rails 3 - 2

    我正在尝试为每个ajax请求显示一个加载指示器,我在Rails3应用程序中工作。HTML:"loading-indicator",:style=>"display:none")%>CSS:#loading-indicator{position:absolute;left:10px;top:10px;}loading.js:我放在assest/javascripts/$(document).ready(function(){$(document).ajaxSend(function(event,request,settings){$('#loading-indicator').show(

  6. 踏浪而行,逐浪而上| MEME全新版本2.0正式上线 - 2

    踏浪而行,逐浪而上,MEME全新版本2.0乘势而来,荣耀上线,2022年7月27日,全网最难爆仓平台MEME携全新2.0版正式上线!MEME2.0版本探索更多功能,全面升级重新定义合约,体验感更好,交易更流畅,相比于原来的1.0,MEME2.0版本上线后,全面支持独立钱包与邮箱登陆,全网最难爆仓平台!从追赶者到领航者数字资产和区块链的成长过程,如同观察一个生态系统,一个新兴事物从无到有的蓬勃发展,这带给我们的冲击是前所未有的。尽管生态系统已经拥有相当悠久的历史,但数字化技术的出现改变了一切。不同于传统的生态圈,数字生态系统实现了1+1>2的协同效应。MEME全网首家Web3交互交易平台,去中心

  7. javascript - 在 Fabric js 中的两个对象之间添加动画 - 2

    我有一个非常基本的应用程序,可让您创建形状并用一条线将它们连接起来。为此,您需要执行以下操作。Example1.Clicknewanimation2.addrectangle3.addchild4.addcircle您可以移动形状、拖动和调整大小。我想知道是否可以在两个对象之间添加动画。因此,例如,一个小圆球会在两个物体之间的线上移动。我已经查看了fabricjs动画页面上的演示,但不确定是否可以从对象b执行。这是FIDDLE. 最佳答案 我不知道你是否可以在fabric中使用内置的动画功能,因为正如你所说,这些对象可能会自己移动。

  8. javascript - 有没有可行的方法使用JS触发CSS关键帧动画? - 2

    当然,我们可以使用关键帧创建CSS动画,并从那里控制它。但是,理想情况下,我想通过单击按钮来触发此动画-因此单击按钮将是一个事件...@keyframesfade-in{0%{opacity:0;}100%{opacity:1;}}现在,点击时,我想触发这个动画;而不是在CSS动画属性中。 最佳答案 看这里jsfiddle如果您希望每次按下按钮时动画都起作用,请使用此代码:$('button').click(function(){$(".fademe").addClass('animated');setTimeout(functio

  9. javascript - 如何动画绘制一系列线段 - 2

    我想画一个点,大约1秒后我想画下一个点。这是否可能:我已经试过了:functionsimulate(i){setTimeout(function(){drawPoint(vis,i,i);},1000);}for(vari=1;i不幸的是,这是行不通的。它只是立即绘制整条线。 最佳答案 这是行不通的,因为for循环将立即运行到结束,setTimeouts将被同时调度,所有函数将同时触发。取而代之的是,这样做:vari=1;(functionloop(){if(i++>200)return;setTimeout(function(){

  10. javascript - 在 React Native 中动态添加组件时如何启用流畅的动画? - 2

    在我的ReactNative应用程序中,我有一张带有条件的卡片按下按钮时呈现并在触发相同按钮时删除的组件。这是我的代码的样子:this.setState({triggered:!this.state.triggered})}title="ClicktoExpand"/>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolabori

随机推荐