当我尝试在 if-else 方法 '_debugLifecycleState != _ElementLifecycle.defunct' 中使用动画骨架小部件时出现错误:不是真的。”

I got Error when I tried to use animation Skeleton widget in if-else method '_debugLifecycleState != _ElementLifecycle.defunct': is not true."

我想在数据仍在加载时显示骨架小部件,所以我在 FutureBuilder 小部件中使用了 if-else。

这里是框架代码

class Skeleton extends StatefulWidget {
  final double height;
  final double width;

  Skeleton({Key key, this.height = 20, this.width = 200 }) : super(key: key);

  createState() => SkeletonState();
}

class SkeletonState extends State<Skeleton> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  Animation gradientPosition;

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

    gradientPosition = Tween<double>(
      begin: -3,
      end: 10,
    ).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Curves.linear
      ),
    )..addListener(() {
      setState(() {});
    });

    _controller.repeat();
  }

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

  @override
  Widget build(BuildContext context) {
    return Container(
        width:  widget.width,
        height: widget.height, 
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment(gradientPosition.value, 0),
            end: Alignment(-1, 0),
            colors: [Colors.black12, Colors.black26, Colors.black12]
          )
        ),
    );
  }
}

这里我尝试使用骨架小部件

FutureBuilder(
              future: CategoryService.list(),
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                print(snapshot.error);
                return snapshot.hasData
                    ? SingleChildScrollView(
                        scrollDirection: Axis.horizontal,
                        child: CategoryList(
                          categories: snapshot.data,
                        ),
                      )
                    : snapshot.hasError
                        ? Text(
                            snapshot.error.toString(),
                          )
                        : Skeleton(
                            height: 200,
                            width: 200,
                          );
              },
            ),

然后我得到了这个错误

Exception caught by animation library

'package:flutter/src/widgets/framework.dart': Failed assertion: line 4182 pos 12: '_debugLifecycleState != _ElementLifecycle.defunct': is not true. ════════════════════════════════════════════════════════════════════════════════ Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 4182 pos 12: '_debugLifecycleState != _ElementLifecycle.defunct': is not true.

我遇到了这个错误,但应用程序仍然 运行ning 没有问题,但是这个错误显示在调试控制台中,并且在屏幕 运行ning 时始终重复错误。

我确实重新加载了,我停止了它并重新 运行 但那没用,我认为问题出在骨架小部件的处理上。

您可以复制粘贴 运行 下面的完整代码
您可以将 _controller.dispose(); 移动到 super.dispose();
之前 代码片段

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

工作演示

完整代码

import 'package:flutter/material.dart';

class Skeleton extends StatefulWidget {
  final double height;
  final double width;

  Skeleton({Key key, this.height = 20, this.width = 200}) : super(key: key);

  createState() => SkeletonState();
}

class SkeletonState extends State<Skeleton>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  Animation gradientPosition;

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

    gradientPosition = Tween<double>(
      begin: -3,
      end: 10,
    ).animate(
      CurvedAnimation(parent: _controller, curve: Curves.linear),
    )..addListener(() {
        setState(() {});
      });

    _controller.repeat();
  }

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

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.width,
      height: widget.height,
      decoration: BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment(gradientPosition.value, 0),
              end: Alignment(-1, 0),
              colors: [Colors.black12, Colors.black26, Colors.black12])),
    );
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class CategoryService {
  static Future<String> list() async {
    await Future.delayed(Duration(seconds: 5), () {});
    return Future.value("123");
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: FutureBuilder(
        future: CategoryService.list(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          print(snapshot.error);
          return snapshot.hasData
              ? SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: Text(
                    snapshot.data,
                  ),
                )
              : snapshot.hasError
                  ? Text(
                      snapshot.error.toString(),
                    )
                  : Skeleton(
                      height: 200,
                      width: 200,
                    );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}