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

Posted

技术标签:

【中文标题】当我尝试在 if-else 方法中使用动画骨架小部件时出现错误 \'_debugLifecycleState != _ElementLifecycle.defunct\': is not true。”【英文标题】:I got Error when I tried to use animation Skeleton widget in if-else method '_debugLifecycleState != _ElementLifecycle.defunct': is not true."当我尝试在 if-else 方法中使用动画骨架小部件时出现错误 '_debugLifecycleState != _ElementLifecycle.defunct': is not true。” 【发布时间】:2021-01-15 15:32:41 【问题描述】:

我想在数据仍在加载时显示骨架小部件,因此我在 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,
                          );
              ,
            ),

然后我得到了这个错误

动画库捕获的异常

'package:flutter/src/widgets/framework.dart':断言失败:行 4182 位置 12:'_debugLifecycleState!= _ElementLifecycle.defunct':是 不对。 ══════════════════════════════════════════════════ ══════════════════════════════ 抛出了另一个异常: 'package:flutter/src/widgets/framework.dart':断言失败:行 4182 位置 12:'_debugLifecycleState!= _ElementLifecycle.defunct':是 不是真的。

我收到此错误,但应用程序仍在正常运行,但此错误显示在调试控制台中,并且在屏幕运行时始终重复该错误。

我确实重新加载并停止它并重新运行它,但这没用,我认为问题在于处置 Skeleton 小部件。

【问题讨论】:

你的意思是这样的` if (snapshot.hasData) return SingleChildScrollView( scrollDirection: Axis.horizo​​ntal, child: CategoryList( categories: snapshot.data, ), );快照.hasError ? Text(snapshot.error.toString()) : Skeleton( height: 200, width: 200, );` 错误会被修复,但我得到另一个错误,但它仅在调试控制台中显示一次,并且应用程序仍在运行。 @Reign 错误是:EXCEPTION CAUGHT BY WIDGETS LIBRARY The following assertion was thrown building FutureBuilder&lt;List&lt;Category&gt;&gt;(dirty, state: _FutureBuilderState&lt;List&lt;Category&gt;&gt;#4e9c2): A build function returned null. The offending widget is: FutureBuilder&lt;List&lt;Category&gt;&gt; Build functions must never return null. To return an empty space that causes the building widget to fill available room, return "Container()". To return an empty space that takes as little room as possible, return "Container(width: 0.0, height: 0.0)". The relevant error-causing widget was: FutureBuilder&lt;List&lt;Category&gt;&gt;.... 【参考方案1】:

您可以在下面复制粘贴运行完整代码 您可以在super.dispose(); 之前移动_controller.dispose(); 代码sn-p

@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),
      ),
    );
  

【讨论】:

以上是关于当我尝试在 if-else 方法中使用动画骨架小部件时出现错误 '_debugLifecycleState != _ElementLifecycle.defunct': is not true。”的主要内容,如果未能解决你的问题,请参考以下文章

Blender 到 Unity 骨架动画变形

零散记录

零散记录

有没有办法在 Blender 中复制和翻转整个对象、骨架及其动画?

可以使用骨骼动画的对象是哪两种情况

2D骨骼动画工具DragonBones的使用教程