flutter FutureBuilder 小部件中的动画导致无限加载

时间:2021-03-07 23:07:33

标签: flutter flutter-animation

我正在尝试为 FutureBuilder 小部件中的容器设置动画,该小部件向本地主机上的节点 js api 发出请求。 API 似乎没有问题,但我注意到当我不调用 controller.repeat() 时容器会正常呈现。我猜 controller.repeat() 不能很好地异步工作,但我还没有找到任何替代方案。

这是我目前得到的代码:

class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<double> animation;
  void initState() {
    super.initState();
    controller = AnimationController(
        duration: const Duration(milliseconds: 3000), vsync: this);
    animation = Tween<double>(begin: 10, end: 300).animate(controller);
    animation.addListener(() {
      setState(() {});
    });
  }

  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final url = Uri.parse("http://localhost:8080");
    return FutureBuilder(
        future: http.get(url),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            final themeList =
                Map<String, dynamic>.from(jsonDecode(snapshot.data.body));
            final keys = List.from(themeList.keys);
            controller.repeat(); // Container shows when I comment this line out
            return Center(
              child: Container(
                color: Colors.red,
                width: animation.value,
                height: animation.value,
              ),
            );
          } else {
            return Center(child: CircularProgressIndicator());
          }
        });
  }
}

1 个答案:

答案 0 :(得分:0)

请将您的动画小部件分开。在您的代码中,每次 setState(...) 调用都会重新请求 http.get(...)

做这样的事情...

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const Scaffold(
        body: Center(
          child: Home(),
        ),
      ),
    );
  }
}

class Home extends StatelessWidget {
  const Home();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: Future<void>.delayed(const Duration(seconds: 2), () {}),
      builder: (context, snapshot) =>
          snapshot.connectionState == ConnectionState.done
              ? const Center(child: AnimatedContainer())
              : const Center(child: CircularProgressIndicator()),
    );
  }
}

class AnimatedContainer extends StatefulWidget {
  const AnimatedContainer();

  @override
  _AnimatedContainer createState() => _AnimatedContainer();
}

class _AnimatedContainer extends State<AnimatedContainer>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 3000),
      vsync: this,
    );
    _animation = Tween<double>(begin: 10, end: 300).animate(_controller);
    _animation.addListener(() {
      setState(() {});
    });
    // _controller.repeat();
    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      width: _animation.value,
      height: _animation.value,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}