Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter _debugLifecycleState != _ElementLifecycle.defunct': is not true

Tags:

I am showing some animated custom painter progress bar in my app it's showing some error

Error: The following assertion was thrown while notifying listeners for AnimationController:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 4263 pos 12: '_debugLifecycleState != _ElementLifecycle.defunct': is not true.

I have a simple homePage in which I have a navigation bar. I am simply showing the container when navigation change like this

SingleChildScrollView(
            child: Container(
                decoration: BoxDecoration(
                  image: DecorationImage(
                    image: AssetImage("images/sidebg.png"),
                    fit: BoxFit.cover,
                  ),
                ),
                child: Column(
                  children: [
                    pageIndex == 0 ? DashboardScreen() : Container(),
                    pageIndex == 1 ? MapScreen() : Container(),
                    pageIndex == 3 ? ServiceCenter() : Container(),
                    pageIndex == 4 ? ProfileScreen() : Container(),
                  ],
                )),
          ),

Issue is as you can see pages changes when index are changing but when i change the page its showing an error as i mention above in continuesly loop not stopping.

If I remove this progress indicator all is working fine.

This is the progress indicator screen

import 'dart:math' as math;

import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'package:sleek_circular_slider/sleek_circular_slider.dart';
import 'package:liquid_progress_indicator/liquid_progress_indicator.dart';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';

class DashboardScreen extends StatefulWidget {
  @override
  _DashboardScreenState createState() => _DashboardScreenState();
}

class _DashboardScreenState extends State<DashboardScreen> {
  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;

    return Container(
      child: Column(
        children: [
          SizedBox(
            height: height * 0.05,
          ),
          Circular_arc(),

        ],
      ),
    );
  }
}

final Gradient gradient = new LinearGradient(
  colors: <Color>[
    Colors.greenAccent.withOpacity(1.0),
    Colors.yellowAccent.withOpacity(1.0),
    Colors.redAccent.withOpacity(1.0),
  ],
  stops: [
    0.0,
    0.5,
    1.0,
  ],
);

class Circular_arc extends StatefulWidget {
  const Circular_arc({
    Key key,
  }) : super(key: key);

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

class _Circular_arcState extends State<Circular_arc>
    with SingleTickerProviderStateMixin {
  Animation<double> animation;
  AnimationController animController;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    animController =
        AnimationController(duration: Duration(seconds: 3), vsync: this);

    final curvedAnimation =
        CurvedAnimation(parent: animController, curve: Curves.easeInOutCubic);

    animation = Tween<double>(begin: 0.0, end: 2).animate(curvedAnimation)
      ..addListener(() {
        setState(() {});
      });
    animController.repeat(max: 1);
  }

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    return Container(
      child: Stack(
        children: [
          CustomPaint(
            size: Size(300, 300),
            painter: ProgressArc(null, Colors.black54, true),
          ),

          CustomPaint(
            size: Size(300, 300),
            painter: ProgressArc(animation.value, Colors.redAccent, false),
          ),
          Positioned(
            top: height * 0.07,
            left: width * 0.2,
            child: Column(
              children: [
                Image.asset(
                  'images/[email protected]',
                  height: height * 0.045,
                ),
                RichText(
                  text: new TextSpan(
                    // Note: Styles for TextSpans must be explicitly defined.
                    // Child text spans will inherit styles from parent
                    style: new TextStyle(
                      fontSize: 14.0,
                      color: Colors.black,
                    ),
                    children: <TextSpan>[
                      new TextSpan(
                          text: '4.6',
                          style: new TextStyle(
                              fontSize: 40, fontFamily: 'UbuntuRegular')),
                      new TextSpan(
                          text: ' /5',
                          style: TextStyle(
                              fontSize: 25,
                              color: Colors.grey[400],
                              fontFamily: 'UbuntuRegular')),
                    ],
                  ),
                ),
                Text(
                  'FIFTEEN DAYS SCORE',
                  style: TextStyle(
                      color: Colors.grey[400], fontFamily: 'UbuntuMedium'),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

class ProgressArc extends CustomPainter {
  bool isBackground;
  double arc;
  Color progressColor;

  ProgressArc(this.arc, this.progressColor, this.isBackground);

  @override
  void paint(Canvas canvas, Size size) {
    final rect = Rect.fromLTRB(0, 0, 300, 300);
    final startAngle = -math.pi;
    final sweepAngle = arc != null ? arc : math.pi;
    final userCenter = false;
    final paint = Paint()
      ..strokeCap = StrokeCap.round
      ..color = progressColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10;

    if (!isBackground) {
      paint.shader = gradient.createShader(rect);
    }
    canvas.drawArc(rect, startAngle, sweepAngle, userCenter, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }
}

Error is in the continuous loop it's not stopping. And also its starts when I change the page index (mean when I change the navigation from home).

like image 687
Umaiz Khan Avatar asked Jan 10 '21 19:01

Umaiz Khan


1 Answers

In your _CircularArcState, please...

  1. Call animController.forward(); after animController.repeat(max: 1);
  2. To save the state of CircularArc, add mixin AutomaticKeepAliveClientMixin in _CircularArcState. Then override wantKeepAlive and return true. Also, call super.build(context); inside build(...).
import 'dart:math' as math;
import 'dart:ui';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: PageView(
          scrollDirection: Axis.vertical,
          children: [
            DashboardScreen(),
            Container(color: Colors.orange),
            Container(color: Colors.blue),
            Container(color: Colors.green),
          ],
        ),
      ),
    );
  }
}

class DashboardScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;

    return Container(
      child: Column(
        children: [
          SizedBox(
            height: height * 0.05,
          ),
          CircularArc(),
        ],
      ),
    );
  }
}

final Gradient gradient = new LinearGradient(
  colors: <Color>[
    Colors.greenAccent.withOpacity(1.0),
    Colors.yellowAccent.withOpacity(1.0),
    Colors.redAccent.withOpacity(1.0),
  ],
  stops: [0.0, 0.5, 1.0],
);

class CircularArc extends StatefulWidget {
  const CircularArc({
    Key key,
  }) : super(key: key);

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

class _CircularArcState extends State<CircularArc>
    with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
  double width;
  double height;
  Animation<double> animation;

  @override
  void initState() {
    super.initState();

    final AnimationController animController =
        AnimationController(duration: Duration(seconds: 3), vsync: this);
    final curvedAnimation =
        CurvedAnimation(parent: animController, curve: Curves.easeInOutCubic);
    animation = Tween<double>(begin: 0.0, end: 2).animate(curvedAnimation)
      ..addListener(() {
        setState(() {});
      });
    animController.repeat(max: 1);
    animController.forward();
  }

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);

    if (width == null && height == null) {
      width = MediaQuery.of(context).size.width;
      height = MediaQuery.of(context).size.height;
    }

    return Container(
      child: Stack(
        children: [
          CustomPaint(
            size: Size(300, 300),
            painter: ProgressArc(null, Colors.black54, true),
          ),
          CustomPaint(
            size: Size(300, 300),
            painter: ProgressArc(animation.value, Colors.redAccent, false),
          ),
          Positioned(
            top: height * 0.07,
            left: width * 0.2,
            child: Column(
              children: [
                // Image.asset(
                //   'images/[email protected]',
                //   height: height * 0.045,
                // ),
                RichText(
                  text: new TextSpan(
                    // Note: Styles for TextSpans must be explicitly defined.
                    // Child text spans will inherit styles from parent
                    style: new TextStyle(
                      fontSize: 14.0,
                      color: Colors.black,
                    ),
                    children: <TextSpan>[
                      new TextSpan(
                          text: '4.6',
                          style: new TextStyle(
                              fontSize: 40, fontFamily: 'UbuntuRegular')),
                      new TextSpan(
                          text: ' /5',
                          style: TextStyle(
                              fontSize: 25,
                              color: Colors.grey[400],
                              fontFamily: 'UbuntuRegular')),
                    ],
                  ),
                ),
                Text(
                  'FIFTEEN DAYS SCORE',
                  style: TextStyle(
                      color: Colors.grey[400], fontFamily: 'UbuntuMedium'),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

class ProgressArc extends CustomPainter {
  bool isBackground;
  double arc;
  Color progressColor;

  ProgressArc(this.arc, this.progressColor, this.isBackground);

  @override
  void paint(Canvas canvas, Size size) {
    final rect = Rect.fromLTRB(0, 0, 300, 300);
    final startAngle = -math.pi;
    final sweepAngle = arc != null ? arc : math.pi;
    final userCenter = false;
    final paint = Paint()
      ..strokeCap = StrokeCap.round
      ..color = progressColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10;

    if (!isBackground) {
      paint.shader = gradient.createShader(rect);
    }
    canvas.drawArc(rect, startAngle, sweepAngle, userCenter, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }
}
like image 73
rickimaru Avatar answered Sep 30 '22 19:09

rickimaru