In this blog post, I will show you how to make a football Scoreboard app using Flutter, for this tutorial we will use this API: https://www.api-football.com/
this is a nice tutorial where you will learn how to make an HTTP request from a REST API with flutter, so without further ado let’s begin

Project Setup
so before we start coding there’s two things that you must do

sign up and get your API key
add the HTTP package for flutter

after getting your API key open your Flutter project and open the pubspec.yaml file and add this dependency.

dependencies:

   http: ^0.12.2

Now let’s start coding.

Creating the API service class
first of all, we will create a new dart file and call it “api_manager.dart” In this class, we will create the function that will fetch the data for us.

code:

//before let’s add the http package

import ‘dart:convert’;

import ‘package:http/http.dart’;

import ‘package:soccer_tutorial/soccermodel.dart’;

class SoccerApi {
  //now let’s set our variables

  //first : let’s add the endpoint URL

  // we will get all the data from api-sport.io

  // we will just change our endpoint

  //the null means that the match didn’t started yet 

  //let’s fix that

  final String apiUrl =

      “https://v3.football.api-sports.io/fixtures?season=2020&league=39”;
  //In our tutorial we will only see how to get the live matches

  //make sure to read the api documentation to be ables too understand it

  // you will find your api key in your dashboard

  //so create your account it’s free

  //Now let’s add the headers

  static const headers = {
    ‘x-rapidapi-host’: “v3.football.api-sports.io”,
    //Always make sure to check the api key and the limit of a request in a free api

    ‘x-rapidapi-key’: “PUT YOUR API KEY HERE OR IT WILL NOT WORK”

  };
  //Now we will create our method

  //but before this we need to create our model

  //Now we finished with our Model

  Future<List<SoccerMatch>> getAllMatches() async {
    Response res = await get(apiUrl, headers: headers);
    var body;
    if (res.statusCode == 200) {
      // this mean that we are connected to the data base

      body = jsonDecode(res.body);
      List<dynamic> matchesList = body[‘response’];
      print(“Api service: ${body}”); // to debug

      List<SoccerMatch> matches = matchesList
          .map((dynamic item) => SoccerMatch.fromJson(item))
          .toList();
      return matches;
    }
  }
}

Now let’s create the model class, In which we will store our data object for the different data of the API
so create a new file and call it soccermodel.dart and add this code

code:

class SoccerMatch {
  //here we will see the different data

  //you will find every thing you need in the doc

  //I’m not going to use every data, just few ones

  Fixture fixture;
  Team home;
  Team away;
  Goal goal;
  SoccerMatch(this.fixture, this.home, this.away, this.goal);
  factory SoccerMatch.fromJson(Map<String, dynamic> json) {
    return SoccerMatch(
        Fixture.fromJson(json[‘fixture’]),
        Team.fromJson(json[‘teams’][‘home’]),
        Team.fromJson(json[‘teams’][‘away’]),
        Goal.fromJson(json[‘goals’]));
  }
}
//here we will store the fixture

class Fixture {
  int id;
  String date;
  Status status;
  Fixture(this.id, this.date, this.status);
  factory Fixture.fromJson(Map<String, dynamic> json) {
    return Fixture(json[‘id’], json[‘date’], Status.fromJson(json[‘status’]));
  }
}
//here we will store the Status

class Status {
  int elapsedTime;
  String long;
  Status(this.elapsedTime, this.long);
  factory Status.fromJson(Map<String, dynamic> json) {
    return Status(json[‘elapsed’], json[‘long’]);
  }
}
//here we will store the Team data

class Team {
  int id;
  String name;
  String logoUrl;
  bool winner;
  Team(this.id, this.name, this.logoUrl, this.winner);
  factory Team.fromJson(Map<String, dynamic> json) {
    return Team(json[‘id’], json[‘name’], json[‘logo’], json[‘winner’]);
  }
}
//here we will store the Goal data

class Goal {
  int home;
  int away;
  Goal(this.home, this.away);
  //Now we will create a factory method to copy the data from

  // the json file

  factory Goal.fromJson(Map<String, dynamic> json) {
    return Goal(json[‘home’], json[‘away’]);
  }
}

Now we have almost finished we have only to create the UI of the app and call the fetch function

main.dart

import ‘package:flutter/material.dart’;

import ‘package:soccer_tutorial/api_manager.dart’;

import ‘package:soccer_tutorial/pagerbody.dart’;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  @override

  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SoccerApp(),
    );
  }
}

class SoccerApp extends StatefulWidget {
  @override

  _SoccerAppState createState() => _SoccerAppState();
}

class _SoccerAppState extends State<SoccerApp> {
  @override

  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFFFAFAFA),
      appBar: AppBar(
        backgroundColor: Color(0xFFFAFAFA),
        elevation: 0.0,
        title: Text(
          “SOCCERBOARD”,
          style: TextStyle(color: Colors.black),
        ),
        centerTitle: true,
      ),
      //now we have finished the api service let’s call it

      //Now befo re we create Our layout let’s create our API service

      body: FutureBuilder(
        future: SoccerApi()
            .getAllMatches(), //Here we will call our getData() method,

        builder: (context, snapshot) {
          //the future builder is very intersting to use when you work with api

          if (snapshot.hasData) {
            print((snapshot.data).length);
            return PageBody(snapshot.data);
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        }, // here we will buil the app layout

      ),
    );
  }
}
//So as we can see w got our matches data,
// the data size depend on the date and the time so
// you can get as many data as many matches are curetly playing
//Now let’s try to get data by seasons and leagues

we need to create some widget in separate files like this

pagebody.dart

import ‘package:flutter/material.dart’;

import ‘package:soccer_tutorial/goalstat.dart’;

import ‘package:soccer_tutorial/matchtile.dart’;

import ‘package:soccer_tutorial/teamstat.dart’;

import ‘soccermodel.dart’;

Widget PageBody(List<SoccerMatch> allmatches) {
  return Column(
    children: [
      Expanded(
        flex: 2,
        child: Container(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 18.0, vertical: 24.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                teamStat(“Local Team”, allmatches[0].home.logoUrl,
                    allmatches[0].home.name),
                goalStat(allmatches[0].fixture.status.elapsedTime,
                    allmatches[0].goal.home, allmatches[0].goal.away),
                teamStat(“Visitor Team”, allmatches[0].away.logoUrl,
                    allmatches[0].away.name),
              ],
            ),
          ),
        ),
      ),
      Expanded(
        flex: 5,
        child: Container(
          width: double.infinity,
          decoration: BoxDecoration(
            color: Color(0xFF4373D9),
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(40.0),
              topRight: Radius.circular(40.0),
            ),
          ),
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(
                  “MATCHES”,
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 24.0,
                  ),
                ),
                Expanded(
                  child: ListView.builder(
                    itemCount: allmatches.length,
                    itemBuilder: (context, index) {
                      return matchTile(allmatches[index]);
                    },
                  ),
                )
              ],
            ),
          ),
        ),
      )
    ],
  );
}

goalstat.dart file

import ‘package:flutter/material.dart’;

Widget goalStat(int expandedTime, int homeGoal, int awayGoal) {
  var home = homeGoal;
  var away = awayGoal;
  var elapsed = expandedTime;
  if (home == null) home = 0;
  if (away == null) away = 0;
  if (elapsed == null) elapsed = 0;
  return Expanded(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          “${elapsed}'”,
          style: TextStyle(
            fontSize: 30.0,
          ),
        ),
        Expanded(
          child: Center(
            child: Text(
              “${home} – ${away}”,
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 36.0,
              ),
            ),
          ),
        )
      ],
    ),
  );
}

matchstat.dart

import ‘package:flutter/material.dart’;

Widget teamStat(String team, String logoUrl, String teamName) {
  return Expanded(
    child: Column(
      children: [
        Text(
          team,
          style: TextStyle(
            fontSize: 18.0,
          ),
        ),
        SizedBox(
          height: 10.0,
        ),
        Expanded(
          child: Image.network(
            logoUrl,
            width: 54.0,
          ),
        ),
        SizedBox(
          height: 10.0,
        ),
        Text(
          teamName,
          textAlign: TextAlign.center,
          style: TextStyle(
            fontSize: 18.0,
          ),
        ),
      ],
    ),
  );
}

matchtile.dart

import ‘package:flutter/material.dart’;

import ‘soccermodel.dart’;

Widget matchTile(SoccerMatch match) {
  var homeGoal = match.goal.home;
  var awayGoal = match.goal.away;
  if (homeGoal == null) homeGoal = 0;
  if (awayGoal == null) awayGoal = 0;
  return Container(
    margin: EdgeInsets.symmetric(vertical: 12.0),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Expanded(
          child: Text(
            match.home.name,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.white,
              fontSize: 16.0,
            ),
          ),
        ),
        Image.network(
          match.home.logoUrl,
          width: 36.0,
        ),
        Expanded(
          child: Text(
            “${homeGoal} – ${awayGoal}”,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.white,
              fontSize: 16.0,
            ),
          ),
        ),
        Image.network(
          match.away.logoUrl,
          width: 36.0,
        ),
        Expanded(
          child: Text(
            match.away.name,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.white,
              fontSize: 16.0,
            ),
          ),
        ),
      ],
    ),
  );
}

And we have finished, try to run the app and see your beautiful application alive. if you liked this project don’t forget to share it and you can tell us what you want to see for the next post,

 

In this blog post, I will show you how to make a football Scoreboard app using Flutter, for this tutorial we will use this API: https://www.api-football.com/

this is a nice tutorial where you will learn how to make an HTTP request from a REST API with flutter, so without further ado let’s begin

Project Setup

so before we start coding there’s two things that you must do
  1. sign up and get your API key
  2. add the HTTP package for flutter
after getting your API key open your Flutter project and open the pubspec.yaml file and add this dependency.
dependencies:
   http: ^0.12.2
Now let’s start coding.

Creating the API service class

first of all, we will create a new dart file and call it “api_manager.dart” In this class, we will create the function that will fetch the data for us.
code:
//before let’s add the http package
import ‘dart:convert’;

import ‘package:http/http.dart’;
import ‘package:soccer_tutorial/soccermodel.dart’;

class SoccerApi {
  //now let’s set our variables
  //first : let’s add the endpoint URL
  // we will get all the data from api-sport.io
  // we will just change our endpoint
  //the null means that the match didn’t started yet 
  //let’s fix that
  final String apiUrl =
      “https://v3.football.api-sports.io/fixtures?season=2020&league=39”;
  //In our tutorial we will only see how to get the live matches
  //make sure to read the api documentation to be ables too understand it

  // you will find your api key in your dashboard
  //so create your account it’s free
  //Now let’s add the headers
  static const headers = {
    ‘x-rapidapi-host’: “v3.football.api-sports.io”,
    //Always make sure to check the api key and the limit of a request in a free api
    ‘x-rapidapi-key’: “PUT YOUR API KEY HERE OR IT WILL NOT WORK”
  };

  //Now we will create our method
  //but before this we need to create our model

  //Now we finished with our Model
  Future<List<SoccerMatch>> getAllMatches() async {
    Response res = await get(apiUrl, headers: headers);
    var body;

    if (res.statusCode == 200) {
      // this mean that we are connected to the data base
      body = jsonDecode(res.body);
      List<dynamic> matchesList = body[‘response’];
      print(“Api service: ${body}”); // to debug
      List<SoccerMatch> matches = matchesList
          .map((dynamic item) => SoccerMatch.fromJson(item))
          .toList();

      return matches;
    }
  }
}

Now let’s create the model class, In which we will store our data object for the different data of the API
so create a new file and call it soccermodel.dart and add this code
code:
class SoccerMatch {
  //here we will see the different data
  //you will find every thing you need in the doc
  //I’m not going to use every data, just few ones

  Fixture fixture;
  Team home;
  Team away;
  Goal goal;
  SoccerMatch(this.fixture, this.home, this.away, this.goal);

  factory SoccerMatch.fromJson(Map<Stringdynamic> json) {
    return SoccerMatch(
        Fixture.fromJson(json[‘fixture’]),
        Team.fromJson(json[‘teams’][‘home’]),
        Team.fromJson(json[‘teams’][‘away’]),
        Goal.fromJson(json[‘goals’]));
  }
}

//here we will store the fixture
class Fixture {
  int id;
  String date;
  Status status;
  Fixture(this.id, this.date, this.status);

  factory Fixture.fromJson(Map<Stringdynamic> json) {
    return Fixture(json[‘id’], json[‘date’], Status.fromJson(json[‘status’]));
  }
}

//here we will store the Status
class Status {
  int elapsedTime;
  String long;
  Status(this.elapsedTime, this.long);

  factory Status.fromJson(Map<Stringdynamic> json) {
    return Status(json[‘elapsed’], json[‘long’]);
  }
}

//here we will store the Team data
class Team {
  int id;
  String name;
  String logoUrl;
  bool winner;
  Team(this.id, this.name, this.logoUrl, this.winner);

  factory Team.fromJson(Map<Stringdynamic> json) {
    return Team(json[‘id’], json[‘name’], json[‘logo’], json[‘winner’]);
  }
}

//here we will store the Goal data
class Goal {
  int home;
  int away;
  Goal(this.home, this.away);

  //Now we will create a factory method to copy the data from
  // the json file
  factory Goal.fromJson(Map<Stringdynamic> json) {
    return Goal(json[‘home’], json[‘away’]);
  }
}

Now we have almost finished we have only to create the UI of the app and call the fetch function
main.dart
import ‘package:flutter/material.dart’;
import ‘package:soccer_tutorial/api_manager.dart’;
import ‘package:soccer_tutorial/pagerbody.dart’;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SoccerApp(),
    );
  }
}

class SoccerApp extends StatefulWidget {
  @override
  _SoccerAppState createState() => _SoccerAppState();
}

class _SoccerAppState extends State<SoccerApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFFFAFAFA),
      appBar: AppBar(
        backgroundColor: Color(0xFFFAFAFA),
        elevation: 0.0,
        title: Text(
          “SOCCERBOARD”,
          style: TextStyle(color: Colors.black),
        ),
        centerTitle: true,
      ),
      //now we have finished the api service let’s call it
      //Now befo re we create Our layout let’s create our API service
      body: FutureBuilder(
        future: SoccerApi()
            .getAllMatches(), //Here we will call our getData() method,
        builder: (context, snapshot) {
          //the future builder is very intersting to use when you work with api
          if (snapshot.hasData) {
            print((snapshot.data).length);
            return PageBody(snapshot.data);
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        }, // here we will buil the app layout
      ),
    );
  }
}
//So as we can see w got our matches data,
// the data size depend on the date and the time so
// you can get as many data as many matches are curetly playing
//Now let’s try to get data by seasons and leagues
we need to create some widget in separate files like this
pagebody.dart
import ‘package:flutter/material.dart’;
import ‘package:soccer_tutorial/goalstat.dart’;
import ‘package:soccer_tutorial/matchtile.dart’;
import ‘package:soccer_tutorial/teamstat.dart’;
import ‘soccermodel.dart’;

Widget PageBody(List<SoccerMatch> allmatches) {
  return Column(
    children: [
      Expanded(
        flex: 2,
        child: Container(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 18.0, vertical: 24.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                teamStat(“Local Team”, allmatches[0].home.logoUrl,
                    allmatches[0].home.name),
                goalStat(allmatches[0].fixture.status.elapsedTime,
                    allmatches[0].goal.home, allmatches[0].goal.away),
                teamStat(“Visitor Team”, allmatches[0].away.logoUrl,
                    allmatches[0].away.name),
              ],
            ),
          ),
        ),
      ),
      Expanded(
        flex: 5,
        child: Container(
          width: double.infinity,
          decoration: BoxDecoration(
            color: Color(0xFF4373D9),
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(40.0),
              topRight: Radius.circular(40.0),
            ),
          ),
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(
                  “MATCHES”,
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 24.0,
                  ),
                ),
                Expanded(
                  child: ListView.builder(
                    itemCount: allmatches.length,
                    itemBuilder: (context, index) {
                      return matchTile(allmatches[index]);
                    },
                  ),
                )
              ],
            ),
          ),
        ),
      )
    ],
  );
}

goalstat.dart file
import ‘package:flutter/material.dart’;

Widget goalStat(int expandedTime, int homeGoal, int awayGoal) {
  var home = homeGoal;
  var away = awayGoal;
  var elapsed = expandedTime;
  if (home == null) home = 0;
  if (away == null) away = 0;
  if (elapsed == null) elapsed = 0;
  return Expanded(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          “${elapsed}'”,
          style: TextStyle(
            fontSize: 30.0,
          ),
        ),
        Expanded(
          child: Center(
            child: Text(
              “${home} – ${away}”,
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 36.0,
              ),
            ),
          ),
        )
      ],
    ),
  );
}

matchstat.dart
import ‘package:flutter/material.dart’;

Widget teamStat(String team, String logoUrl, String teamName) {
  return Expanded(
    child: Column(
      children: [
        Text(
          team,
          style: TextStyle(
            fontSize: 18.0,
          ),
        ),
        SizedBox(
          height: 10.0,
        ),
        Expanded(
          child: Image.network(
            logoUrl,
            width: 54.0,
          ),
        ),
        SizedBox(
          height: 10.0,
        ),
        Text(
          teamName,
          textAlign: TextAlign.center,
          style: TextStyle(
            fontSize: 18.0,
          ),
        ),
      ],
    ),
  );
}

matchtile.dart
import ‘package:flutter/material.dart’;
import ‘soccermodel.dart’;

Widget matchTile(SoccerMatch match) {
  var homeGoal = match.goal.home;
  var awayGoal = match.goal.away;
  if (homeGoal == null) homeGoal = 0;
  if (awayGoal == null) awayGoal = 0;

  return Container(
    margin: EdgeInsets.symmetric(vertical: 12.0),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Expanded(
          child: Text(
            match.home.name,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.white,
              fontSize: 16.0,
            ),
          ),
        ),
        Image.network(
          match.home.logoUrl,
          width: 36.0,
        ),
        Expanded(
          child: Text(
            “${homeGoal} – ${awayGoal}”,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.white,
              fontSize: 16.0,
            ),
          ),
        ),
        Image.network(
          match.away.logoUrl,
          width: 36.0,
        ),
        Expanded(
          child: Text(
            match.away.name,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.white,
              fontSize: 16.0,
            ),
          ),
        ),
      ],
    ),
  );
}

And we have finished, try to run the app and see your beautiful application alive. if you liked this project don’t forget to share it and you can tell us what you want to see for the next post

,