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")));
}
}
我正在使用 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")));
}
}