Logo's Link
上面是我的代码和图片,用于显示动画计时器列表。第一次创建窗口小部件时,运行此命令没有错误,但是当我将该页面放到底部导航栏中时,我意识到会显示出来。
如果发生以下情况,会发生这种情况: (1)我导航到第二个选项卡并返回到第一个选项卡 (2)我将第二个选项卡设置为默认选项,然后导航到第一个选项卡。 结论:如果我没有将list_builder设置为默认选项卡,那么我什么也看不到。
仅供参考,我从https://medium.com/@lucassaltoncardinali/keeping-state-with-the-bottom-navigation-bar-in-flutter-69e4168878e1获得了导航标签,代码如下所示:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'package:flutter/services.dart';
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
AnimationController controller;
int time = 10;
List<AnimationController> listOfTimer = [];
List<int> listOfTiming = [];
List<String> listOfDisplayTiming = [];
bool loading = true;
String get timerString {
Duration duration = controller.duration * controller.value;
return '${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}';
}
loadJson() async {
String data = await rootBundle.loadString('assets/timer_data.json');
var jsonResult = json.decode(data);
for (int i=0; i<jsonResult.length;i ++){
listOfTiming.add(jsonResult[i]);
}
for (int i=0; i<listOfTiming.length;i ++){
controller = AnimationController(
vsync: this,
duration: Duration(seconds: listOfTiming[i]),
);
listOfTimer.add(controller);
}
}
@override
void initState() {
loadJson();
super.initState();
}
@override
Widget build (BuildContext context) {
return Scaffold(
body: new ListView.builder
( shrinkWrap: true,
itemCount: listOfTimer.length ,
itemBuilder: (BuildContext context, int index) {
return _listItem(index);
}
)
);
}
_listItem(index) {
return Card(
color: Colors.white70,
child: Container(
height: MediaQuery.of(context).size.height / 3.65,
child: Padding(
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Positioned.fill(
child: AnimatedBuilder(
animation: listOfTimer[index],
builder: (BuildContext context, Widget child) {
// the display of pink countdown circle
return CustomPaint(
painter: TimerPainter(
animation: listOfTimer[index],
backgroundColor: Colors.black,
color: Colors.orange,
),
willChange: true,
);
},
),
),
Column(
// the display of timer countdown
children: <Widget>[
Text(
"Timer",
style: TextStyle(fontSize: 15,
color: Colors.black,
),
),
AnimatedBuilder(
animation: listOfTimer[index],
builder: (BuildContext context, Widget child) {
return Countdown(
animation: StepTween(
begin: listOfTiming[index],
end: 0,
).animate(listOfTimer[index]),
);
// return Text(
// timerString,
// textScaleFactor: 2.9,
// style: TextStyle(color: Colors.white),
//
// );
}),
],
),
],
),
Container(
child: Row(
children: <Widget>[
FloatingActionButton(
child: AnimatedBuilder(
animation: listOfTimer[index],
builder: (BuildContext context, Widget child) {
return Icon(listOfTimer[index].isAnimating
? Icons.pause
: Icons.play_arrow,
color: Colors.black,
);
// Icon(isPlaying
// ? Icons.pause
// : Icons.play_arrow);
},
),
onPressed: () {
// setState(() => isPlaying = !isPlaying);
if (listOfTimer[index].isAnimating) {
listOfTimer[index].stop(canceled: true);
} else {
listOfTimer[index].reverse(
from: listOfTimer[index].value == 0.0
? 1.0
: listOfTimer[index].value);
}
},
backgroundColor: Colors.orange,
)
],
),
)
],
),
),
),
);
}
}
class TimerPainter extends CustomPainter {
TimerPainter({
this.animation,
this.backgroundColor,
this.color,
}) : super(repaint: animation);
final Animation<double> animation;
final Color backgroundColor, color;
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = backgroundColor
..strokeWidth = 5.0
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke;
paint.color = color;
double progress = (1.0 - animation.value) * 2 * math.pi;
canvas.drawArc(Offset.zero & Size(size.width, size.width), math.pi * 1.5, progress, false, paint);
}
@override
bool shouldRepaint(TimerPainter old) {
return animation.value != old.animation.value ||
color != old.color ||
backgroundColor != old.backgroundColor;
}
}
class Countdown extends AnimatedWidget {
Countdown({Key key, this.animation}) : super(key: key, listenable: animation);
Animation<int> animation;
@override
build(BuildContext context) {
Duration clockTimer = Duration(seconds: animation.value);
String timerText =
'${clockTimer.inMinutes.remainder(60).toString()}:${clockTimer.inSeconds.remainder(60).toString().padLeft(2, '0')}';
return Text(
"$timerText",
style: TextStyle(
fontSize: 40,
color: Colors.black,
),
);
}
}
答案 0 :(得分:0)
从BottomNavigationBar中删除const关键字,并在主体下方声明bottomNavigationBar,希望它对您有用。
答案 1 :(得分:0)
问题已解决。问题出在代码的这一部分:
@override
void initState() {
loadJson();
super.initState();
}
显然initState()
将以setState(){}
结尾,以通知我的窗口小部件页面中的更改。在我的代码中,loadJson()实际上在执行initState()
之后完成,因此可以显示注释。一种简单的解决方案是在setState(){}
方法的末尾添加loadJson()
。