SetState 不更新小部件

时间:2021-07-14 23:06:33

标签: flutter flutter-animation

我希望图像变大并且不透明度为 0 并带有动画 我在两个函数 setState()_onpre() 中尝试了 Future.delayed 来改变图像的大小和不透明度,但它并没有改变小部件

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

class splatch extends StatefulWidget {
  static String id = 'splatch';
  @override
  _splatchState createState() => _splatchState();
}

class _splatchState extends State<splatch> {
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    double _height =  300;
    double _width = 3;


    Future.delayed(const Duration(milliseconds: 500), () {
      setState(() {
        _height = 40;
        _width = 40;
      });

    });

    _onpre() {
        setState(() {
          _height = 40;
        });
    }

    return Container(
      child: Stack(
        children: [
            AnimatedContainer(duration: Duration(microseconds: 100),
              height: _height,
              child:Container(
                child: Image.asset('images/rond1.png'),
              ),
              curve: Curves.fastOutSlowIn,
            ),
        ]
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:2)

我修复了你的代码。

一些重要的部分:

  • 不要在 build 小部件中添加函数。
  • 动画作品需要trigger。在这种方法中,我使用了 ElevatedButton
class splatch extends StatefulWidget {
  static String id = 'splatch';
  @override
  _splatchState createState() => _splatchState();
}

class _splatchState extends State<splatch> {
  late Size size;
  double _height = 300;
  double _width = 3;

  _anim2() async {
    Future.delayed(const Duration(milliseconds: 500), () {
      setState(() {
        _height = 40;
        _width = 40;
      });
    });
  }

  _anim1() {
    setState(() {
      _height = 500;
      _width = 500;
    });
  }

  @override
  Widget build(BuildContext context) {
    size = MediaQuery.of(context).size;
    return Scaffold(
      body: Container(
        child: Column(
          children: [
            AnimatedContainer(
              duration: Duration(seconds: 3),
              height: _height,
              child: Container(
                height: 200,
                width: 200,
                child: Icon(Icons.add),
                color: Colors.red,
              ),
              curve: Curves.fastOutSlowIn,
            ),
            ElevatedButton(
              onPressed: () {
                _anim1();
              },
              child: Text("Animation 1"),
            ),
            SizedBox(
              height: 50,
            ),
            ElevatedButton(
              onPressed: () {
                _anim2();
              },
              child: Text("Animation 2"),
            )
          ],
        ),
      ),
    );
  }
}

答案 1 :(得分:2)

您需要了解 setState((){}) 工作原理的基础知识,每当您在 set-state 的帮助下更改变量时,它都会找到使用它的小部件并将它们标记为脏,然后重建这些脏的小部件在 build 函数的帮助下,在这个过程中,它被多次调用。因此,始终将您的初始化代码放在 initState 中。

** 也修正了你的类名

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

class Splatch extends StatefulWidget {
  static String id = 'splatch';
  @override
  _splatchState createState() => _splatchState();
}

class _splatchState extends State<Splatch> {
  Size size;
  double _height, _width;

  @override
  initState() {
    super.initState();
    size = MediaQuery.of(context).size;
    _height = 300;
    _width = 3;
  }

  _onpre() {
    setState(() {
      _height = 40;
    });
  }

  futureCode() async {
    Future.delayed(const Duration(milliseconds: 500), () {
      setState(() {
        _height = 40;
        _width = 40;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Stack(children: [
        AnimatedContainer(
          duration: Duration(microseconds: 100),
          height: _height,
          child: Container(
            child: Image.asset('images/rond1.png'),
          ),
          curve: Curves.fastOutSlowIn,
        ),
      ]),
    );
  }
}