Skip to content

Project MD

Hardikb19 edited this page Apr 1, 2020 · 5 revisions

We'll be introducing you to the Flutter and App Development in general, to build apps for real life use.

Table of Contents

Introduction to Github

Github-logo

Github is a free and open-source version control system, that helps you keep track of changes to files in a filesystem/repository over time. It has been an industry standard for a while now. Git comes with the git-shell which has a set of nifty commands that can help you do all sorts of things on your repositories.

Github is a service that hosts your repositories online and lets you collaborate with others through it. You can use Github through the browser or the git-shell on your pc.

How to Install Git and Github

  • Installing Git on Windows

    Download Git from Git for Windows and install it

  • Installing Git on Linux

Determine onwhich Linux distribution your system is based on. See List of Linux distributions – Wikipedia for a list. Most Linux systems – including Ubuntu – are Debian-based.

Debian-based linux systems

Open a terminal window. Copy & paste the following into the terminal window and hit Return. You may be prompted to enter your password.

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git

You can use Git now.

  • Installing Git on a Mac

Open a terminal window.

Step 1 – Install Homebrew

Homebrew simplifies the installation of software on the Mac OS X operating system.

Copy & paste the following into the terminal window and hit Return.

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew doctor

You will be offered to install the Command Line Developer Tools from Apple. Confirm by clicking Install. After the installation finished, continue installing Homebrew by hitting Return again.

Step 2 – Install Git

Copy & paste the following into the terminal window and hit Return.

brew install git

You can use Git now.

Commands required

First, create a Github ID, then move on.

  • Clone to a repository
    git clone https://github.com/{username}/{repo_name}.git

  • Initialize a repository in the directory(this is just for information, you won't need this for any task) git init <Project Name>

  • Create a branch
    git checkout -b <branch-name>

  • Change into another branch
    git checkout <branch-name>

  • Adding Files to be committed
    git add <filename1> <folder_name>\<filename2> - Adds filename1 in current directory and filename2 in the folder.
    git add . - Adds all files in the current directory

  • Adding a commit message
    git commit -m "<message>"

  • checking status of files
    git status

  • Pushing the committed changes to the GitHub repository
    git push origin <branch-name>
    Note: Never push to the master branch, create your own branch and change into that and then push.

  • Pulling changes from the GitHub repository
    git pull origin <branch-name>

A detailed article on Git and Github: https://medium.com/@abhishekj/an-intro-to-git-and-github-1a0e2c7e3a2f

Flutter Path - Windows

Extract the flutter folder from the zip you downloaded in C: drive.

  1. Navigate in to Flutter SDK folder (in our case C:\Flutter)
  2. Go inside to bin folder and copy the directory path (in your case C:\Flutter\bin)
  3. Go to “Control Panel > User Accounts > User Accounts > Change my environment variables”
  4. Under “User variables” select path variable and click edit.

  1. In new dialog box click on New button, pasted the path to your Flutter bin folder. Then click OK. (Move up the flutter path to the top, using the "Move Up" option on the right)

Confirm everything with Flutter Doctor in Command Prompt(Run as Administrator)
flutter doctor

Flutter Overview

Flutter is an open-source UI software development kit created by Google. It is used to develop applications for Android, iOS, Windows, Mac, Linux, Google Fuchsia and the web.

Installation

Windows

To setup Flutter on Windows, follow these official guidelines

MacOS

To setup Flutter on MacOS, follow these official guidelines

Linux

To setup Flutter on Linux, follow these official guidelines

Flutter Doctor

Flutter comes up with an awesome command line utility to check if your machine is set up for local development. Flutter has Flutter Doctor command


Flutter Doctor


Flutter Doctor for Windows Doesn't need XCode. Refer to Installation above

It help guide developers through setting up the local development environment for both iOS and Android. Flutter Doctor inspects which tools are installed on the local machine and which tools need to be configured. Once the Flutter Doctor command is happy, we can carry on creating a new Flutter app.

Editor

So for your default editor , we recommend you guys to use VSCode , as its a lightweight IDE compared to Android Studio.

Project Structure

Let’s first see what’s in the project generated by the Flutter framework:


Flutter Default Code Overview


  • lib/ - just as pub (Dart’s package manager), all the code will be here. All files which help you render the app will have a .dart extension
  • lib/main.dart - In the main.dart file, you create widgets and develop Flutter apps as per your needs
  • pubspec.yaml - stores a list of packages that are required to run the application, just like package.json does it. You should remember that in Flutter projects you cannot use pub directly, but instead, you will use the Flutter command: flutter pub get <package_name>. If using VSCode, pubspec.yaml page has a download button on the side which runs the above command for all packages you need
  • ios/ & android/ - the code specific for each platform, including app icons and settings where you set what permissions you’ll need for your application (like access to location, Bluetooth). So to switch app icons or to allow some special features like ARCore to run on your device, you need to changes specifics here.

Adding assets to your application

First we need to make an assets folder and add the necessary images or fonts that we need to import

Assets Folder

Then we need to add that assets under the pubsec.yaml

Pubsec.yaml

Adding Packages

If we need to add features to our application we need to use packages , for example we need to launch urls from our application then we can use this package. Url Launcher

First we need to add that package in our pubsec.yaml file

Url_launcher

Then we need to import that package in our code

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

Widgets

Now that you have installed flutter and are beginning to develop, We want to introduce you to what exactly widgets are, in layman's term everything you use or interact with or even see on an app is a Widget.

Widget only one requirement: its method must returns other Widgets. The only exception to this rule are low-level widgets like 'Text' that return primitive types (Strings or numbers, usually.)

This may sound intimidating at first, but you'll get along with the flow, Easiest way to visualize how Widgets work is to think of it as a complex tool with gears and levers and pulleys, basically built of simpler machines. When we build an app, we return a MaterialApp Widget which encloses other Widgets

Widget build(BuildContext buildcontext){ //Here you return a Widget from the build function and the parameter it receives is a BuildContext object

return MaterialApp(                       // MaterialApp takes in a few parameters, as they are default parameters(Parameters with predefined values), if you wish to update any such parameter you explicitly mention the parameter and its value
      title: 'Welcome to Flutter',        // title here takes in a String input, hence "title : 'Welcome to Flutter'"
      home: Scaffold(                     // home takes in a Widget, for which we send a Scaffold Widget. Note: Scaffold holds all contents you'll be showing on your app
        appBar: AppBar(                   // appBar is a parameter of Scaffold which usually is provided with a Widget called AppBar. AppBar is the top bar you see in most apps which contain the menu and the search options
          title: Text('Hello World'),     // title again takes a Widget for which we provide a Text Widget. This provides for the title on the AppBar
        ),
        body: Center(                     // body contains the main content of your App which also takes in Widget 
          child: Container(
             child: Text('First App')
          )
        )
      )
 );
}

If you ever wanna see what parameters are there for a specific widget press Ctrl+Space on VS-Code it shows you all the parameters for any Widget

If you ever wanna know which Widgets to use refer to Flutter's Widget Catalog

Flutter has its own youtube Channel as well which on which you can view videos for the Widgets you want to use.

Link : https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw

Stateless and Stateful Widgets

Now we know how easy it is to use widgets. The next logical step would be to create our widgets. There are basically two kinds of widgets. They are called stateless and stateful widgets.

“Stateless” doesn’t mean they don’t have a state at all. Widgets is a Dart class, that can be declared with properties. But changing those properties in a stateless widget won’t affect what has already been rendered. Updating properties of a stateful widget will trigger life cycle hooks and render its content using the new state. We’ll start with Stateless widgets as they seem to be a bit easier.

Stateless Widgets

To create one, we need:

  1. A name for the new class
  2. To extend our class from StatelessWidget.
  3. Implement the build() method, that will receive one argument of type BuildContext and return a result of type Widget.

I have nothing more to add about Stateless widgets. They are simple.

Refer to this article to know more

Stateful Widgets

The following is the basic syntax of any Stateful Widget class.

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Container(color: const Color(0xFFFFE306));
  }
}

So, here first, we have declared our main class called MyApp which extends the StatefulWidget class. That means now we have to define the generic method called createState() in that class which will return one another class which extends the generic class State

Refer to this article to know more.

Flutter Basics

Let's understand the default flutter code.

Import statements

This is where we import all the packages necessary for our flutter application.

import 'package:flutter/material.dart';

Main

This is just starting point of our application , here we are calling our root widget , this is just like int main() in C or public static void main() in Java

void main() => runApp(MyApp());

Root Widget

This is root widget of your application , Title property of the home page is being set as Flutter Demo Home Page and under Theme we have color scheme as blue.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(   
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

Home page

This is the Homepage that will contain the body and other widgets in our application.

Here MyHomepage is a statefulWidget , which means the State of the homepage can be changed at anytime during the lifetime of our application, here we change the state when we click the button and increase the counter.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

Lets look at different components on the homepage and see what they are doing.

The onPressed property will call the function which will increment our counter , and we add an icon on the button , by giving the icon to the child.

floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),

This function will increment the counter and SetState will update the the value of the counter , so that our application will reflect the changes.

int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

We will use the Text Widget to display the value of the counter , that will be updated everytime we click the button.

children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],

We encourage you guys to play around with the code , make some changes and see what happens.

Check out this tutorial to learn more.

Widget Tree

If all of this class-nesting is confusing, perhaps this visual of the Widget tree will help. This is what your current counter application looks like.

Widget Tree

Sources to refer to:

Flutter Widget Catalog:

Provides all the details about widgets available for UI development. It can be referred here.

Cookbook:

This cookbook contains recipes that demonstrate how to solve common problems while writing Flutter apps. Each recipe is self-contained and can be used as a reference to help you build up an application.

Videos:

Widgets in Flutter - 1

Assets

Flutter apps can include both code and assets (sometimes called resources). An asset is a file that is bundled and deployed with your app, and is accessible at runtime.

Common types of assets include static data (for example, JSON files), configuration files, icons, and images (JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP, and WBMP).

Flutter uses the pubspec.yaml file, located at the root of your project, to identify assets required by an app.

name: eventpagetask
description: Task 1

version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
  assets:            #Indentation is important while adding files
    - logo.png       #Files to be used as assets are provided here
    - oc.png
    - hawkeye.png
    - gambit.png
    - cicada.png 

Steps to add and use Assets in your Project:

  • Create assets folder in your project subdirectory
  • Copy all images to be used as font into this directory
  • Goto pubspec.yaml file in your project and make the necessary changes as shown above
  • Use the Image Assets in your program freely using Image.asset()
...
   
    return Container(
       child: Image.asset('logo.png'),
    );

....

Commonly Used Widgets

For Task 1 we expect you to use certain commonly used Widgets like rows, columns, Containers etc


Image

Here we will be providing you with syntaxes and explanations of how these Widgets are used and exactly what do they represent.


Container

For documentation click here...

A convenience widget that combines common positioning,containing and sizing widgets.

A container first surrounds the child with padding (inflated by any borders present in the decoration) and then applies additional constraints to the padded extent (incorporating the width and height as constraints, if either is non-null). The container is then surrounded by additional empty space described from the margin.

Containers with no children try to be as big as possible unless the incoming constraints are unbounded, in which case they try to be as small as possible. Containers with children size themselves to their children. The width, height, and constraints arguments to the constructor override this.

Widget tile(...)
  {
      ...
      return Container(
        height: ...
        margin: ...
        decoration: BoxDecoration(
          shape: ...
          color: ...
          borderRadius: ...
        ),
        child: Row(children: 
          <Widget>[
             ...
             //Contains children Widgets for Row
             ...
          ],
        )
      );
}

Column

For documentation click here

Column Widget allows a user to arrange its contents vertically.

import 'package:flutter/material.dart';

void main() => runApp(AppTask_1()); //The execution begins here where all the runApp being a function from the imported package executes a constructor of AppTask_1

class AppTask_1 extends StatelessWidget 
{
  @override
  Widget build(BuildContext context) 
  {
    return MaterialApp(
      title: ...
      home: EventPage(title: 'Page_Events'), // an object of EventPage class is sent as parameter for home
    );
  }
}

class EventPage extends StatefulWidget 
{
  EventPage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _EventPageState createState() => _EventPageState();
}

class _EventPageState extends State<EventPage> 
{
  
  Widget tile({String title,String logo,String date, String venue ,String time,BuildContext context})
  {
      ...
      ...
  }


  @override
  Widget build(BuildContext context) 
  {
    return Scaffold(
      appBar: AppBar(
        ...
        title: Text("IECSE Events"),
      ),
      body: Center(          //This center aligns whatever widget is provided to Center as child
        child: Column(       //Column Widget is used to arrange the different tiles vertically
            children: <Widget>[
            tile(...),
            ...
            ... //Call the tile method to return Containers which get distributed in Columns here
          ]
        ),
      ),
    );
  }
}

Row

For Documentation click [here](For documentation click here...

As we see Column distributes content vertically, Row is used for horizontal distribution of contents.

As you see in the example content is horizontally distributed in each tiles, so we need to use a Row Widget

....

Widget tile({String title,...})
{
      Size size = MediaQuery.of(context).size; //Used to take dimensions of the device to make custom apps

      return Container(             //Tile is take as a container
        height: ... //Denotes height of each Tile
        margin: ... //Used for leaving empty space around the Container
        decoration: BoxDecoration(
            ... //Used to Add background, shape, colour gradient, or images to Container
        ),
        child: Row(children: 
          <Widget>[
            Container(
              width: ... //Provided with width of first component
              child: ... //Widget which the container will hold example Text(), Image.asset()
            ),
            Container(
              ...
            ),
            Container(
              ...
            )
          ],
        )
      );
  }
....

Links

HTTP Request and Responses

Here we will be learning about basic GET and POST requests, understanding APIs and using Postman.

What is HTTP?

The Hypertext Transfer Protocol (HTTP) is designed to enable communications between clients and servers.

HTTP works as a request-response protocol between a client and a server.

A web browser may be the client, and an application on a computer that hosts a web site may be the server.

Example: A client (browser) submits an HTTP request to the server; then the server returns a response to the client. The response contains status information about the request and may also contain the requested content.

The various HTTP Methods are:

  • GET
  • POST
  • PUT
  • HEAD
  • DELETE
  • PATCH
  • OPTIONS

We will be dealing only with GET and POST methods.

The Get Method

The GET methods are used to receive a response from a server or API.

The Post Method

The POST method is used to submit an entry to a server, which results in a change in state.

What is HTTP Request?

An HTTP request is made by a client, to a named host, which is located on a server. The aim of the request is to access a resource on the server.

To make the request, the client uses components of a URL (Uniform Resource Locator), which includes the information needed to access the resource. The components of a URL explains URLs.

A correctly composed HTTP request contains the following elements:

  1. A request line.
  2. A series of HTTP headers, or header fields.
  3. A message body, if needed.

Read about HTTP requests in detail

What is HTTP Response?

HTTP Response is the packet of information sent by Server to the Client in response to an earlier Request made by Client. HTTP Response contains the information requested by the Client.

An HTTP response contains:

  1. A status line.
  2. A series of HTTP headers, or header fields.
  3. A message body, which is usually needed.

Read about HTTP responses in detail

JSON

What is JSON?

JSON stands for JavaScript Object Notation. It is a lightweight format for storing and transporting data often used when data is sent from a server to a web page

Why do we use JSON?

When exchanging data between a browser and a server, the data can only be text. JSON is text, and we can convert any JavaScript object into JSON, and send JSON to the server. We can also convert any JSON received from the server into JavaScript objects. This way we can work with the data as JavaScript objects, with no complicated parsing and translations.

JSON Syntax Rules

  • Data is in name/value pairs
  • Data is separated by commas
  • Curly braces hold objects
  • Square brackets hold an array

JSON Values

In JSON, values must be one of the following data types:

  • a string
  • a number
  • an object (JSON object)
  • an array
  • a boolean
  • null

Go through this tutorial to learn about the basics of JSON

Go through this tutorial to learn about JSON Data Types

API

An application program interface (API) is a set of routines, protocols, and tools for building software applications. Basically, an API specifies how software components should interact. Additionally, APIs are used when programming graphical user interface (GUI) components. A good API makes it easier to develop a program by providing all the building blocks. A programmer then puts the blocks together.

An API may be for a web-based system, operating system, database system, computer hardware, or software library.

Read this article to get a better understanding about APIs

Below are some fun APIs you can interact with:

Interacting with APIs

We will be using Postman for sending GET and POST requests to APIs. You can download the app from here

For using Postman, an example is given where we will interact with the Tronald Dump API

Image1

  • Then, open the Postman app and click on the '+' icon.

Image2

  • Paste the link and click on the 'Send' button.

Image3

  • The response can be seen in the body tab.

Image4

  • The quote is the string associated with "value"

Image5

Similarly you can explore the documentation of other APIs and interact with them.

Widgets in Flutter - 2

Here are a few Widgets you will be needing for this task, make sure you read about them and their extensive functionality can be understood by googling them or watching a youtube tutorial on how to use them.

AppBar

To insert an App bar in an app, flutter provides it as a property in the Scaffold widget.

@override

 Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Klimatic'),backgroundColor: Colors.deepOrange,),  
      //This adds an AppBar which contains Klimatic as the title and has a deeporange colour
      body: Center(child: Text('My Page!')),

Imgur

You can see the full documentation for the AppBar class, here

Scroll down to the properties section to see what other properties you can add.

Icon

To insert icons into your app, you can use the icon class

Row(
     children: <Widget>[
         Container(child: Icon(Icons.star_border,color: Colors.deepOrange,),
             padding: EdgeInsets.all(20),),
         Container(child: Icon(Icons.people,color: Colors.deepOrange,),
              padding: EdgeInsets.all(20),),
        ],
    )

// This inserts a Row of two icons

Imgur

You can see the full documentation for the Icon class, here

The list of all icons available in flutter is given here, under the Constants heading

Text

The Text widget displays a string of text with a single style. The string might break across multiple lines or might all be displayed on the same line depending on the layout constraints

Text(
  'Hello, How are you?',
  textAlign: TextAlign.center,
  style: TextStyle(fontWeight: FontWeight.bold),
)

// This inserts a Text which reads, "Hello, How are you?" 
// The text is aligned to the centre of the widget, the Text class is a child of.
// The style parameter can be used for changing the colour, font height, font-weight and many other properties

Imgur

You can see the full documentation for the Text class, here

Column

A widget that displays its children in a vertical array. The Column widget does not scroll (and in general it is considered an error to have more children in a Column than will fit in the available room). If you have a line of widgets and want them to be able to scroll if there is insufficient room, consider using a ListView.

Column(
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(10),
              child: Text('Deliver features faster'),),
            Container(
              padding: EdgeInsets.all(10),
              child: Text('Craft beautiful UIs'),)
          ],
        )

// This adds a Column of 2 Texts

Imgur

You can see the full documentation of the Column class, here

Circular Progress Indicator

CircularProgressIndicator can be used as the loading animation you see when an application is busy, or it can also be used to show the progress in terms of a pie chart or an arc

CircularProgressIndicator(
                              value: 0.8,
                              valueColor: AlwaysStoppedAnimation(Colors.cyan),
                              strokeWidth: 8.0,
                          )

Imgur

You can see the full documentation of the CircularProgressIndicator class, here

Stack

It is a widget that positions its children relative to the edges of its box. This class is useful if you want to overlap several children in a simple way, for example having some text and an image, overlaid with a gradient and a button attached to the bottom

Stack(
  children: <Widget>[
    // Max Size
    Container(
      color: Colors.green,
    ),
    Container(
      color: Colors.blue,
      height: 300.0,
      width: 300.0,
    ),
    Container(
      color: Colors.pink,
      height: 150.0,
      width: 150.0,
    )
  ],
),

Imgur

The above code forms a stack of widgets as shown below:

You can see the documentation for the Stack class, here

ListView

Since the Column widget is not scrollable, we use the ListView class to display widgets vertically and to be able to scroll if the size of the widgets is greater than the size of the screen.

ListView(
  padding: const EdgeInsets.all(8),
  children: <Widget>[
    Container(
      height: 350,
      color: Colors.red,
    ),
    Container(
      height: 350,
      color: Colors.green,
    ),
    Container(
      height: 350,
      color: Colors.blue,
    ),
  ],
)

Imgur

As you can see in the above image, the blue container cannot fit in the screen, so we can scroll down in the list. If you would have used the Column widget instead of ListView, it would have shown an overflow.

Imgur

You can see the full documentation of the ListView class, here

TextFormField

TextFormField is used to take input from the user which is used by TextEditingController which together is used to take input from the user. The input is typed into the TextFormField and the controller is used to manage the data input into the textfield

static TextEditingController _cityFieldController = new TextEditingController();
final searchfield = new TextFormField(
    decoration: new InputDecoration(
      hintText: 'Enter City',
    ),
    autofocus: false,
  controller: _cityFieldController,
  style: TextStyle(fontFamily: "Quantico"),
);

Gesture Detector

Gesture Detectors are used to identify the type of user input provided by touch, tap or simulation

          GestureDetector(
              child: Container(child:Icon(Icons.search)),
              onLongPress: (){
                _cityFieldController = new TextEditingController(text:defaultCity); //Resets on long press
              },
              onTap: (){ //On single tap, searches..
                setState(() {
                  _cityEntered = _cityFieldController.text; //Sets City to input
                });
                build(context); //Rebuilds UI
              },
            )

You can read about async, await and Futures to learn how to fetch data

Fetching Data

To fetch data from an API you would be this code snippet

  void showStuff() async {
    Map data = await getWeather(apiID,defaultCity);
    print(data.toString());
  }

  Future<Map> getWeather(String apiId, String city) async {
      String apiURL = 'https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiId&units=metric';

      http.Response response = await http.get(apiURL);
      print(json.decode(response.body));
      return json.decode(response.body);
  }

It fetches the data as Response and returns the JSON as a Map object which is recieved in function showStuff() and response is loaded into data

Displaying data

If you notice that when you are fetching data, your code initially has nothing to render on screen so you get a red error screen, now you need to build the data at runtime so that live data can be displayed to the User

We use FutureBuilder for this purpose.

  Widget displayData()
  {
    return new FutureBuilder(future: getWeather(apiID, _cityEntered == null ? defaultCity : _cityEntered) , 
                  builder: (BuildContext context, AsyncSnapshot<Map> snapshot){

                    if(snapshot.hasData)
                    {
                          return ....
                    }
          }
}

Links :

Clone this wiki locally