Flutter 数字时钟小部件在视图更改后立即导致错误

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

我正在使用 https://pub.dev/packages/slide_digital_clock,它会导致内存泄漏和动画错误垃圾邮件,我不知道如何修复它,只要将视图发送回注销就会发生这种情况。如果有人可以解释说明如何修复它,将不胜感激

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,
                        ),)),
                )
              ],
            ),
          ],
        ),
      ),

    ),
  ),
);
}
}

完成小部件树时抛出了以下断言: _SpinnerTextState#321b2(ticker active) 已与活动的 Ticker 一起处理。

_SpinnerTextState 通过其 SingleTickerProviderStateMixin 创建了一个 Ticker,但在对 mixin 调用 dispose() 时,该 Ticker 仍然处于活动状态。 Ticker 必须在调用 super.dispose() 之前被释放。

应通过调用 AnimationController 本身的 dispose() 来处理 AnimationController 使用的代码。否则,代码会泄露。

动画库捕获异常 在通知 AnimationController 的侦听器时抛出以下断言: 'package:flutter/src/widgets/framework.dart':断言失败:第 4109 行第 12 行:'_lifecycleState != _ElementLifecycle.defunct':不正确。

动画库捕获异常 'package:flutter/src/widgets/framework.dart':断言失败:第 4109 行第 12 行:'_lifecycleState != _ElementLifecycle.defunct':不正确。

动画库捕获异常 'package:flutter/src/widgets/framework.dart':断言失败:第 4109 行第 12 行:'_lifecycleState != _ElementLifecycle.defunct':不正确。

这个包有两个错误,有两个拉取请求来修复这些问题,但是你必须手动合并它们,因为这两个拉取请求没有被所有者合并
第 1 步:更新 lib/helpers/spinner_text.dart https://github.com/caglarylmz/slide_digital_clock/pull/4/files/23cd40ac4f32fc7adeab4101af498994d40d43fd
变化自

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

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

第 2 步:取消定时器,更新 class _DigitalClockState https://github.com/caglarylmz/slide_digital_clock/pull/1/commits/5a648954e83e8215180e05db5bbf9e232e4d385a
代码片段

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

手动合并这两个拉取请求后的工作演示

工作演示的完整代码

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")));
  }
}