flutter 如何使容器居中?

rnmwe5a2  于 2023-01-02  发布在  Flutter
关注(0)|答案(2)|浏览(182)

这是我目前的设计:

我想实现这个设计:

正如您所看到的,容器从顶部开始,我想做的是像第二个屏幕截图一样将其居中。
这是我的代码:

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pomodoro/5.hourglass_animation/countdown_timer/responsive.dart';

class StartPomodoro extends StatefulWidget {
  const StartPomodoro({super.key, });

  //final DateTime end;

  @override
  State<StartPomodoro> createState() => _StartPomodoroState();
}

class _StartPomodoroState extends State<StartPomodoro>
    with TickerProviderStateMixin {
  final now = DateTime.now();

  List<bool> isSelected = [true, false];
  late Timer timer;
  late AnimationController controller;

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

  double progress = 1.0;
  bool LongBreak = true;

  void notify() {
    if (countText == '00:00:00') {}
  }

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 0),
    );
    controller.addListener(() {
      notify();
      if (controller.isAnimating) {
        setState(() {
          progress = controller.value;
        });
      } else {
        setState(() {
          progress = 1.0;
          LongBreak = true;
        });
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    ThemeData themeData = Theme.of(context);
    return SafeArea(
      child: Scaffold(
        backgroundColor:
            LongBreak ? const Color(0xffD94530) : const Color(0xff6351c5),
        body: GestureDetector(
          onTap: () {
            if (controller.isDismissed) {
              showModalBottomSheet(
                context: context,
                builder: (context) => Container(
                  height: 300,
                  child: CupertinoTimerPicker(
                    initialTimerDuration: controller.duration!,
                    onTimerDurationChanged: (time) {
                      setState(() {
                        controller.duration = time;
                      });
                    },
                  ),
                ),
              );
            }
          },
          child: AnimatedBuilder(
              animation: controller,
              builder: (context, child) {
                return Stack(
                  children: <Widget>[
                    Align(
                      alignment: Alignment.bottomCenter,
                      child: Container(
                        color: const Color(0xffD94530),
                        height: controller.value *
                            MediaQuery.of(context).size.height *
                            0.722,
                      ),
                    ),
                   Spacer(),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      
                      child: Responsive(
                        
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: <Widget>[
                            Align(
                              alignment: Alignment.bottomCenter,
                              child: Align(
                                alignment: FractionalOffset.bottomCenter,
                                child: Padding(
                                  padding: const EdgeInsets.symmetric(
                                      vertical: 2.0, horizontal: 15.0),
                                  child: Container(
                                    width: MediaQuery.of(context).size.width,
                                    height: 210,
                                    decoration:  BoxDecoration(
                                      borderRadius: BorderRadius.circular(20),
                                      color:
                                          const Color(0xffFAFAFA)
                                    ),
                                    child: Container(
                                      padding: const EdgeInsets.all(20.0),
                                      child: SingleChildScrollView(
                                        child: Column(
                                          mainAxisAlignment: MainAxisAlignment.center,
                                          crossAxisAlignment:
                                              CrossAxisAlignment.start,
                                          children: [
                                            const Text(
                                              "Hyper-focused on... (+add task)",
                                              style: TextStyle(
                                                fontSize: 22.0,
                                                fontWeight: FontWeight.w500,
                                              ),
                                            ),
                                            const SizedBox(height: 16),
                                            Center(
                                              child: SingleChildScrollView(
                                                child: Column(
                                                  mainAxisAlignment:
                                                      MainAxisAlignment.center,
                                                  children: [
                                                    Row(
                                                      mainAxisAlignment:
                                                          MainAxisAlignment
                                                              .center,
                                                      children: [
                                                        Text(
                                                          countText,
                                                          style: const TextStyle(
                                                            fontWeight:
                                                                FontWeight.w600,
                                                            letterSpacing: 4,
                                                            fontSize: 65.0,
                                                            color:
                                                                Color(0xff3B3B3B),
                                                          ),
                                                        ),
                                                      ],
                                                    ),
                                                    Row(
                                                      mainAxisAlignment:
                                                          MainAxisAlignment
                                                              .center,
                                                      children: const [
                                                        Text(
                                                          '    Hours      Minutes     Seconds    ',
                                                          style: TextStyle(
                                                            fontWeight:
                                                                FontWeight.w500,
                                                            letterSpacing: 2,
                                                            fontSize: 20.0,
                                                            color:
                                                                Color(0xff3B3B3B),
                                                          ),
                                                        ),
                                                      ],
                                                    ),
                                                  ],
                                                ),
                                              ),
                                            ),
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                            Spacer(),
                            Responsive( 
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                crossAxisAlignment:
                                    CrossAxisAlignment.stretch,
                                children: [
                                  AnimatedBuilder(
                                      animation: controller,
                                      builder: (context, child) {
                                        return Padding(
                                          padding:
                                              const EdgeInsets.symmetric(
                                                  vertical: 2.0,
                                                  horizontal: 15.0),
                                          child:
                                              FloatingActionButton.extended(
                                                  backgroundColor:
                                                      const Color(
                                                          0xffFAFAFA),
                                                  onPressed: () {
                                                    if (controller
                                                        .isAnimating) {
                                                      controller.stop();
                                                      setState(() {
                                                        LongBreak = false;
                                                      });
                                                    } else {
                                                      controller.reverse(
                                                          from: controller
                                                                      .value ==
                                                                  0
                                                              ? 1.0
                                                              : controller
                                                                  .value);
                                                      setState(() {
                                                        LongBreak = false;
                                                      });
                                                    }
                                                  },
                                                  icon: Icon(
                                                    controller.isAnimating
                                                        ? Icons.pause
                                                        : Icons.play_arrow,
                                                    color: const Color(
                                                        0xff3B3B3B),
                                                  ),
                                                  label: Text(
                                                    controller.isAnimating
                                                        ? "Pause"
                                                        : "Start",
                                                    style: const TextStyle(
                                                        color: Color(
                                                            0xff3B3B3B)),
                                                  )),
                                        );
                                      }),
                                 ],
                              ),
                            ),
                            SizedBox(height: 10,),
                          ],
                        ),
                      ),
                    ),
                  ],
                );
              }),
        ),
      ),
    );
  }

  AnimationController _buildClockAnimation(TickerProvider tickerProvider) {
    return AnimationController(
      vsync: tickerProvider,
      duration: const Duration(milliseconds: 750),
    );
  }

  void _animateLeftDigit(
    int prev,
    int current,
    AnimationController controller,
  ) {
    final prevFirstDigit = (prev / 10).floor();
    final currentFirstDigit = (current / 10).floor();
    if (prevFirstDigit != currentFirstDigit) {
      controller.forward();
    }
  }
}

由于某种原因,我无法将 Package 了小部件的容器居中

center

运气不好,我怎么能把计时器容器居中呢?
谢谢你能提供的任何帮助

iswrvxsc

iswrvxsc1#

由于大量的代码和不正确的缩进,很难弄清楚完整的代码。但据我所知,您面临这个问题是因为使用Spacer
Spacer正在将您的floating buttontimer Container推到尽头。
尝试删除Spacer,然后用Center Package timer Container,再用Flexible Package 它,这样应该可以解决您的问题。
您目前的代码大致为:

Column
|_ Timer Container
|_ Spacer
|_ Floating Button

将其更改为:

Column
|_ Flexible
  |_ Center
    |_ Timer Container
|_ Floating Button
wbgh16ku

wbgh16ku2#

如果您喜欢使用Stack widget,请使用Stack上的AlingPositioned等位置widget。根据您的UI,使用stack widget结构将

return Stack(
  children: <Widget>[
    background(context),
    Align(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: buildCounter(context),
      ),
    ),
    Align(
      alignment: Alignment.bottomCenter,
      child: startPauseButtonBuild(),
    ),
  ],
);

这是完整的代码段,我删除了一些最小和填充小部件,以处理一些空间

void main() => runApp(MaterialApp(home: const StartPomodoro()));

class StartPomodoro extends StatefulWidget {
  const StartPomodoro({
    super.key,
  });

  @override
  State<StartPomodoro> createState() => _StartPomodoroState();
}

class _StartPomodoroState extends State<StartPomodoro>
    with TickerProviderStateMixin {
  final now = DateTime.now();

  List<bool> isSelected = [true, false];
  late Timer timer;
  late AnimationController controller;

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

  double progress = 1.0;
  bool LongBreak = true;

  void notify() {
    if (countText == '00:00:00') {}
  }

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 0),
    );
    controller.addListener(() {
      notify();
      if (controller.isAnimating) {
        setState(() {
          progress = controller.value;
        });
      } else {
        setState(() {
          progress = 1.0;
          LongBreak = true;
        });
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    ThemeData themeData = Theme.of(context);
    return SafeArea(
      child: Scaffold(
        backgroundColor:
            LongBreak ? const Color(0xffD94530) : const Color(0xff6351c5),
        body: GestureDetector(
          onTap: () {},
          child: AnimatedBuilder(
              animation: controller,
              builder: (context, child) {
                return Stack(
                  children: <Widget>[
                    background(context),
                    Align(
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: buildCounter(context),
                      ),
                    ),
                    Align(
                      alignment: Alignment.bottomCenter,
                      child: startPauseButtonBuild(),
                    ),
                  ],
                );
              }),
        ),
      ),
    );
  }

  Widget startPauseButtonBuild() {
    return LayoutBuilder(
      builder: (_, constraints) => Padding(
        padding: const EdgeInsets.all(8.0),
        child: AnimatedBuilder(
            animation: controller,
            builder: (context, child) {
              return Padding(
                padding:
                    const EdgeInsets.symmetric(vertical: 2.0, horizontal: 15.0),
                child: SizedBox(
                  width: constraints.maxWidth,
                  child: FloatingActionButton.extended(
                    backgroundColor: const Color(0xffFAFAFA),
                    onPressed: () {},
                    icon: Icon(
                      controller.isAnimating ? Icons.pause : Icons.play_arrow,
                      color: const Color(0xff3B3B3B),
                    ),
                    label: Text(
                      controller.isAnimating ? "Pause" : "Start",
                      style: const TextStyle(color: Color(0xff3B3B3B)),
                    ),
                  ),
                ),
              );
            }),
      ),
    );
  }

  Column buildCounter(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Align(
          alignment: Alignment.bottomCenter,
          child: Container(
            width: MediaQuery.of(context).size.width,
            height: 210,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(20),
                color: const Color(0xffFAFAFA)),
            child: Container(
              padding: const EdgeInsets.all(20.0),
              child: SingleChildScrollView(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      "Hyper-focused on... (+add task)",
                      style: TextStyle(
                        fontSize: 22.0,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                    const SizedBox(height: 16),
                    Center(
                      child: SingleChildScrollView(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Text(
                                  countText,
                                  style: const TextStyle(
                                    fontWeight: FontWeight.w600,
                                    letterSpacing: 4,
                                    fontSize: 65.0,
                                    color: Color(0xff3B3B3B),
                                  ),
                                ),
                              ],
                            ),
                            Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: const [
                                Text(
                                  '    Hours      Minutes     Seconds    ',
                                  style: TextStyle(
                                    fontWeight: FontWeight.w500,
                                    letterSpacing: 2,
                                    fontSize: 20.0,
                                    color: Color(0xff3B3B3B),
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }

  Align background(BuildContext context) {
    return Align(
      alignment: Alignment.bottomCenter,
      child: Container(
        color: const Color(0xffD94530),
        height: controller.value * MediaQuery.of(context).size.height * 0.722,
      ),
    );
  }

  AnimationController _buildClockAnimation(TickerProvider tickerProvider) {
    return AnimationController(
      vsync: tickerProvider,
      duration: const Duration(milliseconds: 750),
    );
  }

  void _animateLeftDigit(
    int prev,
    int current,
    AnimationController controller,
  ) {
    final prevFirstDigit = (prev / 10).floor();
    final currentFirstDigit = (current / 10).floor();
    if (prevFirstDigit != currentFirstDigit) {
      controller.forward();
    }
  }
}

相关问题