Home > Back-end >  How to separate different widgets alongside another widget?
How to separate different widgets alongside another widget?

Time:12-25

This is my problem:

as you can see, the widgets are stacked

I want to achieve this design:

The app bar and timer are separated there, not stacked

How can I separate one to each other, first the homePageTimerUI and below the countDownTimer ?

This is my code: 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;
  }
}

This is my own attempt to solve the issue, but didn't work

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

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

How can achieve this design?

enter image description here

Thank you for any help you can offer

CodePudding user response:

Try wrap CountDownTimer with Expanded widget like this:

Column(
  children: [
    HomePageTimerUI(),
    Expanded(child: CountDownTimer()),
  ],
)

CodePudding user response:

Are you asking for Stack() widget? You want to replace one for another? You could use AnimatedSwitcher().

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

Where MyWidget() is asigned to the widget you want to show via SetState(). The widgets are switched with a nice animation.

If you need to have one Widget placed one above the other in the vertical axis, you should try to remove the scaffold and the SizedBox with infity values.

CodePudding user response:

if this class can't stack. Just using static type. add these codes at the same file with CountDownTimer.

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

Then, you must import this file and call this widget by this parameter. example

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

but you don't need to use StackPages just put countDownTimer in your pages.

  • Related