简体   繁体   中英

Flutter digital clock widget causing errors as soon as the view is changed

Im using https://pub.dev/packages/slide_digital_clock and its causing memory leak and animation error spam and i do not how to fix it, this happens as soon as the the view is sent back to logout. if any one can explain show how it can be fixed it would be much appreciated

import 'dart:convert';
import 'package:flutter/widgets.dart';
import 'package:attenv02/login_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:geolocator/geolocator.dart';
import 'package:slide_digital_clock/slide_digital_clock.dart';
import 'package:intl/intl.dart';

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}


class _HomePageState extends State<HomePage> {
 var locationMessege= "";
 bool timeinbtn = true;
 bool timeoutbtn = false;
 String name = "";

 void initState() {
 super.initState();
 }

Future <String> loadPref()async{
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return Future.delayed(Duration(seconds: 1),()async{
  return await sharedPreferences.getString("useFullName");
});

}


 logout()async{
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.clear();
sharedPreferences.commit();
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) 
=> LoginPage()), (Route<dynamic> route) => false);
}


void getCurrentLocation()async{
var position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
var lastPosition=await Geolocator.getLastKnownPosition();
String now =await new DateFormat.yMd().add_Hm().format(new DateTime.now());
timeinbtn=!timeinbtn;
timeoutbtn=!timeoutbtn;
print(lastPosition);
print(now);

setState(() {
  locationMessege="$position.latitude,$position.longitude,$now";
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    backgroundColor:Color.fromRGBO(255, 191, 68, 1),
    title:FutureBuilder(
      future: loadPref(),
      builder: (context, snapshot) {
        if(snapshot.hasData){
          return Text("${snapshot.data}");
        }else{
          return Text("Loading");
        }
      },
    ),
    actions: <Widget>[
      FlatButton(
        onPressed: () {
          logout();
        },
        child: Text("Log Out", style: TextStyle(color: Colors.white)),
      ),
    ],
  ),
  body: Container(
    decoration: BoxDecoration(
        image: DecorationImage(
            image: AssetImage("assets/bg.jpg"), fit: BoxFit.cover)),
    child: Center(
      child: Container(
        padding: EdgeInsets.all(30),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [

            Column(
              children:<Widget>  [
                Container(
                    child:DigitalClock(
                      digitAnimationStyle: Curves.elasticOut,
                      is24HourTimeFormat: false,
                      areaDecoration: BoxDecoration(
                        color: Colors.transparent,
                      ),
                      hourMinuteDigitTextStyle: TextStyle(
                        color: Colors.blueGrey,
                        fontSize: 50,
                      ),
                      amPmDigitTextStyle: TextStyle(color: Colors.blueGrey, fontWeight: FontWeight.bold),
                    ),
                ),

                Text("Position:$locationMessege",style:TextStyle(
                    color: Colors.black,
                    fontSize: 10.0,
                    fontWeight: FontWeight.bold)),
                Visibility(
                  visible:timeinbtn,
                  child: FlatButton(onPressed:(){
                    getCurrentLocation();
                  },
                      color: Colors.orange,
                      child: Text("Time in",
                        style: TextStyle(
                          color: Colors.white,
                        ),)),
                ),
                Visibility(
                  visible: timeoutbtn,
                  child: FlatButton(onPressed:(){
                    getCurrentLocation();
                  },
                      color: Colors.orange,
                      child: Text("Time out",
                        style: TextStyle(
                          color: Colors.white,
                        ),)),
                )
              ],
            ),
          ],
        ),
      ),

    ),
  ),
);
}
}

The following assertion was thrown while finalizing the widget tree: _SpinnerTextState#321b2(ticker active) was disposed with an active Ticker.

_SpinnerTextState created a Ticker via its SingleTickerProviderStateMixin, but at the time dispose() was called on the mixin, that Ticker was still active. The Ticker must be disposed before calling super.dispose().

Tickers used by AnimationControllers should be disposed by calling dispose() on the AnimationController itself. Otherwise, the ticker will leak.

Exception caught by animation library The following assertion was thrown while notifying listeners for AnimationController: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 4109 pos 12: '_lifecycleState.= _ElementLifecycle:defunct'. is not true.

Exception caught by animation library 'package:flutter/src/widgets/framework.dart': Failed assertion: line 4109 pos 12: '_lifecycleState.= _ElementLifecycle:defunct'. is not true.

Exception caught by animation library 'package:flutter/src/widgets/framework.dart': Failed assertion: line 4109 pos 12: '_lifecycleState.= _ElementLifecycle:defunct'. is not true.

This package has two bugs and there are two pull requests to fix these issues, but you have to merge them manually because these two pull requests did not merge by owner
Step 1: update lib/helpers/spinner_text.dart https://github.com/caglarylmz/slide_digital_clock/pull/4/files/23cd40ac4f32fc7adeab4101af498994d40d43fd
change from

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

to

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

Step 2: Cancel timer, update class _DigitalClockState https://github.com/caglarylmz/slide_digital_clock/pull/1/commits/5a648954e83e8215180e05db5bbf9e232e4d385a
code snippet

Timer _timer;
...
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
...
  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

working demo after manually merged these two pull requests

在此处输入图像描述

full code of working demo

import 'package:flutter/material.dart';
import 'package:slide_digital_clock/slide_digital_clock.dart';

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

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

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  var locationMessege = "";
  bool timeinbtn = true;
  bool timeoutbtn = false;
  String name = "";

  void initState() {
    super.initState();
  }

  Future<String> loadPref() async {
    /*SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    return Future.delayed(Duration(seconds: 1), () async {
      return await sharedPreferences.getString("useFullName");
    });*/

    return Future.value("useFullName");
  }

  logout() async {
    Navigator.of(context).pushAndRemoveUntil(
        MaterialPageRoute(builder: (BuildContext context) => LoginPage()),
        (Route<dynamic> route) => false);
  }

  void getCurrentLocation() async {
    /*var position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    var lastPosition = await Geolocator.getLastKnownPosition();
    String now = await new DateFormat.yMd().add_Hm().format(new DateTime.now());
    timeinbtn = !timeinbtn;
    timeoutbtn = !timeoutbtn;
    print(lastPosition);
    print(now);

    setState(() {
      locationMessege = "$position.latitude,$position.longitude,$now";
    });*/
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Color.fromRGBO(255, 191, 68, 1),
        title: FutureBuilder(
          future: loadPref(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text("${snapshot.data}");
            } else {
              return Text("Loading");
            }
          },
        ),
        actions: <Widget>[
          FlatButton(
            onPressed: () {
              logout();
            },
            child: Text("Log Out", style: TextStyle(color: Colors.white)),
          ),
        ],
      ),
      body: Container(
        /*decoration: BoxDecoration(
            image: DecorationImage(
                image: NetworkImage("https://picsum.photos/250?image=9"),
                fit: BoxFit.cover)),*/
        child: Center(
          child: Container(
            padding: EdgeInsets.all(30),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Column(
                  children: <Widget>[
                    Container(
                      child: DigitalClock(
                        digitAnimationStyle: Curves.elasticOut,
                        is24HourTimeFormat: false,
                        areaDecoration: BoxDecoration(
                          color: Colors.transparent,
                        ),
                        hourMinuteDigitTextStyle: TextStyle(
                          color: Colors.blueGrey,
                          fontSize: 50,
                        ),
                        amPmDigitTextStyle: TextStyle(
                            color: Colors.blueGrey,
                            fontWeight: FontWeight.bold),
                      ),
                    ),
                    Text("Position:$locationMessege",
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 10.0,
                            fontWeight: FontWeight.bold)),
                    Visibility(
                      visible: timeinbtn,
                      child: FlatButton(
                          onPressed: () {
                            getCurrentLocation();
                          },
                          color: Colors.orange,
                          child: Text(
                            "Time in",
                            style: TextStyle(
                              color: Colors.white,
                            ),
                          )),
                    ),
                    Visibility(
                      visible: timeoutbtn,
                      child: FlatButton(
                          onPressed: () {
                            getCurrentLocation();
                          },
                          color: Colors.orange,
                          child: Text(
                            "Time out",
                            style: TextStyle(
                              color: Colors.white,
                            ),
                          )),
                    )
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: Center(child: Text("Login Page")));
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM