在flutter中使用底部导航选项卡时显示页面时出现问题

时间:2020-05-21 13:05:07

标签: flutter dart flutter-animation

Logo's Link

list of timer

上面是我的代码和图片,用于显示动画计时器列表。第一次创建窗口小部件时,运行此命令没有错误,但是当我将该页面放到底部导航栏中时,我意识到会显示出来。

enter image description here

如果发生以下情况,会发生这种情况: (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,
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:0)

从BottomNavigationBar中删除const关键字,并在主体下方声明bottomNavigationBar,希望它对您有用。

答案 1 :(得分:0)

问题已解决。问题出在代码的这一部分:

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

  }

显然initState()将以setState(){}结尾,以通知我的窗口小部件页面中的更改。在我的代码中,loadJson()实际上在执行initState()之后完成,因此可以显示注释。一种简单的解决方案是在setState(){}方法的末尾添加loadJson()