Robert Tomic
Robert Tomic

Reputation: 33

How to call two widgets separately from StatelessWIdget that is in another dart file

So I am new to Flutter and I want to make a simple scoreboard with its timer and everything. The problem is that I got two files screen_result and time. In screen_result I have a screen and buttons to operate the scoreboard, in time I have a stopwatch and its control buttons in it.

What I want is to call separately widget build Time below score and widget build Buttons next to other buttons for controlling scoreboard. I do that but nothing happens when I press button to start time. So I am doing something wrong but don't know what.

screen_result.dart

import 'package:flutter/material.dart';
import 'time.dart';

class Screen extends StatefulWidget {
  @override
  _ScreenState createState() => _ScreenState();
}

class _ScreenState extends State<Screen> {
  int result_home = 0;
  int result_away = 0;

  Widget build(BuildContext context) {
    return new Scaffold(
        body: SingleChildScrollView(
            child: Column(children: <Widget>[
      Row(
        //ROW 1
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          //-------------------------RESULT HOME
          Container(
            color: Colors.green,
            margin: EdgeInsets.all(0.0),
            height: 500,
            width: 300,
            alignment: Alignment.topCenter,
            child: new Text(
              '$result_home',
              style: new TextStyle(
                fontSize: 100.0,
                color: Colors.white,
              ),
            ),
          ),
          //------------------------TIME SPACE
          Column(
            children: [
              Container(
                color: Colors.green,
                margin: EdgeInsets.all(0.0),
                height: 150,
                width: 450,
                alignment: Alignment.topCenter,
                child: new Text(
                  ':',
                  style: new TextStyle(
                    fontSize: 100.0,
                    color: Colors.white,
                  ),
                ),
              ),
              Container(
                color: Colors.green,
                margin: EdgeInsets.all(0.0),
                height: 350,
                width: 450,
                alignment: Alignment.topCenter,
                child: TimeState().buiildTime(),
              ),
            ],
          ),
          //-------------------------------RESULT AWAY
          Container(
            color: Colors.green,
            margin: EdgeInsets.all(0.0),
            height: 500,
            width: 300,
            alignment: Alignment.topCenter,
            child: new Text(
              '$result_away',
              style: new TextStyle(
                fontSize: 100.0,
                color: Colors.white,
              ),
            ),
          ),
        ],
      ),
      Row(//ROW 2
          children: [
        Flexible(
          fit: FlexFit.tight,
          flex: 1,
          child: Container(
              color: Colors.blue,
              height: 200,
              child: Column(
                children: [
                  SizedBox(
                    width: 150,
                    height: 100,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        primary: Colors.yellow[700],
                        onPrimary: Colors.red,
                      ),
                      onPressed: () {
                        setState(() {
                          result_home++;
                        });
                      },
                      child: new Text(
                        "GOAL HOME",
                        style: new TextStyle(
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                  SizedBox(
                    width: 150,
                    height: 100,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        primary: Colors.yellow[700],
                        onPrimary: Colors.red,
                      ),
                      onPressed: () {
                        if (result_home > 0) {
                          setState(() {
                            result_home--;
                          });
                        }
                      },
                      child: new Text(
                        "NO GOAL",
                        style: new TextStyle(
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                ],
              )),
        ),

        Flexible(
          fit: FlexFit.tight,
          flex: 1,
          child: Column(
                children: [
                  Container(
                    width: 150,
                    height: 100, 
                    child: TimeState().buildButtons()
                  ),
                  
                ],
              ),
        ),


        Flexible(
          fit: FlexFit.tight,
          flex: 1,
          child: Container(
              color: Colors.blue,
              height: 200,
              child: Column(
                children: [
                  SizedBox(
                    width: 150, 
                    height: 100, 
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        primary: Colors.yellow[700],
                        onPrimary: Colors.red,
                      ),
                      onPressed: () {
                        setState(() {
                          result_away++;
                        });
                      },
                      child: new Text(
                        "GOAL AWAY",
                        style: new TextStyle(
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                  SizedBox(
                    width: 150,
                    height: 100,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        primary: Colors.yellow[700],
                        onPrimary: Colors.red,
                      ),
                      onPressed: () {
                        if (result_away > 0) {
                          setState(() {
                            result_away--;
                          });
                        }
                      },
                      child: new Text(
                        "NO GOAL",
                        style: new TextStyle(
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                ],
              )),
        ),
      ]),
    ])));
  }
}

time.dart

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'button.dart';
    
    
    class Time extends StatefulWidget {
      @override
      State<Time> createState() => TimeState();
    }
    
    class TimeState extends State<Time> {
      Duration duration = Duration();
      Timer? timer;
    
      late String time;
       final myController = TextEditingController();
      
      @override
      void initState() {
        super.initState();
    
        reset();
      }
    
      void reset() {
        setState(() => duration = Duration());
      }
    
      void addTime() {
        final addSeconds = 1;
    
        setState(() {
          final seconds = duration.inSeconds + addSeconds;
    
          duration = Duration(seconds: seconds);
          time = duration.toString();
        });
      }
    
      void startTimer({bool resets = true}) {
        if (resets) {
          reset();
        }
    
        timer = Timer.periodic(Duration(seconds: 1), (_) => addTime());
      }
    
      void stopTimer({bool resets = true}) {
        if (resets) {
          reset();
        }
    
        setState(() {
          timer?.cancel();
        });
      }
    
      void firstHalfEnd() {
        setState(() => duration = Duration(minutes: 45, seconds: 00));
        stopTimer(resets: false);
      }
    
    
      void secondHalfEnd() {
        setState(() => duration = Duration(minutes: 90, seconds: 00));
        stopTimer(resets: false);
      }
    
      void addMinute (){
    
    setState(() {
     duration = duration + Duration(minutes: 1);
    });
    
      }
    
      void subtractMinute (){
    
    setState(() {
     duration = duration - Duration(minutes: 1);
    });
    
      }
    
      @override
      Widget build(BuildContext context) => Scaffold(
            backgroundColor:
                Colors.green, 
            body: Center(
                child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                buiildTime(),
                SizedBox(
                  height: 20,
                ), 
                buildButtons()
              ],
            )),
          );
    
      Widget buiildTime() {
        String twoDigits(int n) => n.toString().padLeft(
            2, '0'); // pretvara jednoznamenkaste brojeve u "dvoznamenkaste" 9 -> 09
        final minutes = twoDigits(duration.inMinutes.remainder(100));
        final seconds = twoDigits(duration.inSeconds.remainder(60));
    
        return Text(
          '$minutes:$seconds',
          style: TextStyle(fontSize: 20),
          
        );
      }
    
      Widget buildButtons() {
        bool time_going = timer == null ? false : timer!.isActive;
        bool time_stops = duration.inSeconds == 0;
       
    
        return time_going || !time_stops
            ? Column(
                mainAxisAlignment: MainAxisAlignment.center,
                
                children: [
                  Row(
                    children: [
                      ButtonWidget(
                          text: time_going ? 'PAUSE' : 'RESUME',
                          onClicked: () {
                            if (time_going) {
                              stopTimer(resets: false);
                            } else {
                              startTimer(resets: false);
                            }
                          }),
                      SizedBox(
                        width: 12,
                      ),
                      ButtonWidget(text: "RESET", onClicked:  reset,),
                    ],
                  ),
                   SizedBox(
                        
                        height: 10,
                      ),
                  Row(
                    
                  crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      ButtonWidget(
                        text : '1. Half END',
                        color: Colors.white,
                        backgroundColor: Colors.blue,
                        onClicked: firstHalfEnd,
                        
                        
                         ),
    
                        SizedBox(width: 10,),
                        SizedBox(
                        
                        child:ButtonWidget(
                        text : '2. Half END',
                        color: Colors.white,
                        backgroundColor: Colors.blue,
                        onClicked: secondHalfEnd,
    
                         )),
                         ],
                  ),
                  Row(
                    children: [
                   
                   ElevatedButton(onPressed: addMinute, child: Text('+1 minute')),
                   SizedBox(width: 10,),
                   ElevatedButton(onPressed: subtractMinute, child: Text('-1 minute'))
    
                      
                    ],
                  )
                ],
              )
            : ButtonWidget(
                text: "Start Timer!",
                color: Colors.black,
                backgroundColor: Colors.white,
                onClicked: () {
                  startTimer();
                });
      }
    }

button.dart

    import 'package:flutter/material.dart';
    
    class ButtonWidget extends StatelessWidget {
      final String text;
      final Color color;
      final Color backgroundColor;
      final VoidCallback onClicked;
    
      const ButtonWidget({Key? key, required this.text, required this.onClicked,
        this.color = Colors.white, this.backgroundColor = Colors.black}) : super(key: key);
      @override
      Widget build(BuildContext context) => ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: backgroundColor,
          padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16)
        ),
          onPressed: onClicked,
          child: Text(text,style: TextStyle(fontSize: 15,color: color),)
      );

}

Upvotes: 0

Views: 843

Answers (1)

BBK
BBK

Reputation: 502

Since you are new to Flutter, I would like to give you some tips.

1- There is no need to use the new prefix in the Dart language.

2- Instead, try to use const where needed.

3- To name variables, prefer camelCase, not snake_case.

4- Prefer SizedBox over Container when you need to assign height or width only.

5- Check default values, and try not to override properties unnecessarily.

6- Prefer to use interpolation to compose strings and values. So do not use toString.

7- You should make your Child's widgets(Time, Button) stateless, as their states are handled by the parent(Screen).

If we come to the problem that you faced, you are calling a widget from another State like the following:

child: TimeState().buiildTime(),

Instead, create separate widgets for different needs like you did in button.dart.

So take all your addTime, resetTime, etc. methods and put in to screen.dart and create two different child widget(TimeScore, TimeControlButtons).

If you have further questions, please don't hesitate to write in the comments.

Upvotes: 1

Related Questions