flutter 如何将不同的小部件与另一个小部件分开?

5kgi1eie  于 2022-12-27  发布在  Flutter
关注(0)|答案(2)|浏览(263)

这是我的问题:

我想实现这个设计:

如何将一个与另一个区分开来,首先是homePageTimerUI,然后是countDownTimer?
这是我的代码:homePageTimerUI.dart

class HomePageTimerUI extends StatefulWidget {
  const HomePageTimerUI({Key? key}) : super(key: key);

  @override
  State<HomePageTimerUI> createState() => _HomePageTimerUIState();
}

class _HomePageTimerUIState extends State<HomePageTimerUI> {
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: double.maxFinite,
      width: double.infinity,
      child: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            elevation: 0,
            backgroundColor: Colors.transparent,
            bottom: PreferredSize(
              preferredSize: const Size.fromHeight(40),
              child: Container(
                color: Colors.transparent,
                child: SafeArea(
                  child: Column(
                    children: <Widget>[
                      TabBar(
                          indicator: const UnderlineTabIndicator(
                              borderSide: BorderSide(
                                  color: Color(0xff3B3B3B), width: 4.0),
                              insets:
                                  EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 11.0)),
                          indicatorWeight: 15,
                          indicatorSize: TabBarIndicatorSize.label,
                          labelColor: const Color(0xff3B3B3B),
                          labelStyle: const TextStyle(
                              fontSize: 12,
                              letterSpacing: 1.3,
                              fontWeight: FontWeight.w500),
                          unselectedLabelColor: const Color(0xffD7D7D7),
                          tabs: const [
                            Tab(
                              text: "POMODORO",
                              icon: Icon(Icons.work_history, size: 40),
                            ),
                            Tab(
                              text: "SHORT BREAK",
                              icon: Icon(Icons.ramen_dining, size: 40),
                            ),
                            Tab(
                              text: "LONG BREAK",
                              icon: Icon(Icons.battery_charging_full_rounded,
                                  size: 40),
                            ),
                          ])
                    ],
                  ),
                ),
              ),
            ),
          ),
          body: TabBarView(
            children: const <Widget>[
              // Center(
              //   child: StartPomodoro(),
              // ),
              // Center(
              //   child: ShortBreak(),
              // ),
              // Center(child: LongBreak()),
            ],
          ),
        ),
      ),
    );
  }
}

countDownTimer.dart

class CountDownTimer extends StatefulWidget {
  @override
  _CountDownTimerState createState() => _CountDownTimerState();
}

class _CountDownTimerState extends State<CountDownTimer>
    with TickerProviderStateMixin {
  late AnimationController controller;

  String get timerString {
    Duration duration = controller.duration! * controller.value;
    return '${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}';
  }

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 5),
    );
  }

  @override
  Widget build(BuildContext context) {
    ThemeData themeData = Theme.of(context);
    return Scaffold(
      backgroundColor: Colors.white10,
      body: AnimatedBuilder(
          animation: controller,
          builder: (context, child) {
            return Stack(
              children: <Widget>[
                Align(
                  alignment: Alignment.bottomCenter,
                  child: Container(
                    color: Colors.amber,
                    height:
                        controller.value * MediaQuery.of(context).size.height,
                  ),
                ),
                Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Expanded(
                        child: Align(
                          alignment: FractionalOffset.center,
                          child: Stack(
                            children: <Widget>[
                              CustomPaint(
                                  painter: CustomTimerPainter(
                                animation: controller,
                                backgroundColor: Colors.white,
                                color: themeData.indicatorColor,
                              )),
                              Align(
                                alignment: FractionalOffset.center,
                                child: Column(
                                  mainAxisAlignment:
                                      MainAxisAlignment.spaceEvenly,
                                  crossAxisAlignment:
                                      CrossAxisAlignment.center,
                                  children: <Widget>[
                                    Text(
                                      timerString,
                                      style: TextStyle(
                                          fontSize: 112.0,
                                          color: Colors.white),
                                    ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          AnimatedBuilder(
                              animation: controller,
                              builder: (context, child) {
                                return FloatingActionButton.extended(
                                    onPressed: () {
                                      if (controller.isAnimating)
                                        controller.stop();
                                      else {
                                        controller.reverse(
                                            from: controller.value == 0.0
                                                ? 1.0
                                                : controller.value);
                                      }
                                    },
                                    icon: Icon(controller.isAnimating
                                        ? Icons.pause
                                        : Icons.play_arrow),
                                    label: Text(
                                        controller.isAnimating ? "Pause" : "Play"));
                              }),
                        ],
                      ),
                    ],
                  ),
                ),
              ],
            );
          }),
    );
  }
}

class CustomTimerPainter extends CustomPainter {
  CustomTimerPainter({
    required this.animation,
    required this.backgroundColor,
    required 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 = 10.0
      ..strokeCap = StrokeCap.butt
      ..style = PaintingStyle.stroke;

    canvas.drawCircle(size.center(Offset.zero), size.width / 2.0, paint);
    paint.color = color;
    double progress = (1.0 - animation.value) * 2 * math.pi;
    canvas.drawArc(Offset.zero & size, math.pi * 1.5, -progress, false, paint);
  }

  @override
  bool shouldRepaint(CustomTimerPainter old) {
    return animation.value != old.animation.value ||
        color != old.color ||
        backgroundColor != old.backgroundColor;
  }
}

这是我自己解决问题的尝试,但没有成功

class StackedPages extends StatelessWidget {
  const StackedPages({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        HomePageTimerUI(),
        CountDownTimer(),
      ],
    );
  }
}

怎样才能实现这个设计呢?

谢谢你能提供的任何帮助

k2arahey

k2arahey1#

你是在请求Stack()小部件吗?你想用一个替换另一个吗?你可以使用AnimatedSwitcher()。

AnimatedSwitcher(
        duration: const Duration(seconds: 1), child: MyWidget());

其中,MyWidget()被分配给你想要通过SetState()显示的小部件,小部件之间的切换带有一个漂亮的动画。
如果您需要将一个Widget在垂直轴上上下放置,您应该尝试删除scaffold和带有infity值的SizedBox。

chhkpiq4

chhkpiq42#

如果这个类不能堆叠。只是使用static类型。将这些代码添加到与CountDownTimer相同的文件中。

static const Widget countDownTimer = CountDownTimer();
...
// class CountDownTimer

然后,您必须导入该文件并通过该参数调用该小部件。示例

@override
  Widget build(BuildContext context) {
    return Column(
      children: [
        HomePageTimerUI(),
        countDownTimer,
      ],
    );
  }

但是你不需要使用StackPages,只要把countDownTimer放在你的页面里就行了。

相关问题