-
Notifications
You must be signed in to change notification settings - Fork 1
Project MD
We'll be introducing you to the Flutter and App Development in general, to build apps for real life use.
- Introduction to Github
- Flutter Path - Windows
- Flutter - Overview
- Flutter Basics
- Widgets in Flutter - 1
- HTTP Request and Responses
- Introduction to JSON
- Basics of API
- Widgets in Flutter - 2
- Fetching data
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.
-
Download Git from Git for Windows and install it
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.
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.
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.
Copy & paste the following into the terminal window and hit Return
.
brew install git
You can use Git now.
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
Extract the flutter folder from the zip you downloaded in C: drive.
- Navigate in to Flutter SDK folder (in our case C:\Flutter)
- Go inside to bin folder and copy the directory path (in your case C:\Flutter\bin)
- Go to “Control Panel > User Accounts > User Accounts > Change my environment variables”
- Under “User variables” select path variable and click edit.
- 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 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.
To setup Flutter on Windows, follow these official guidelines
To setup Flutter on MacOS, follow these official guidelines
To setup Flutter on Linux, follow these official guidelines
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 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.
So for your default editor , we recommend you guys to use VSCode , as its a lightweight IDE compared to Android Studio.
Let’s first see what’s in the project generated by the Flutter framework:
-
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.
First we need to make an assets folder and add the necessary images or fonts that we need to import
Then we need to add that assets under the pubsec.yaml
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
Then we need to import that package in our code
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
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
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.
To create one, we need:
- A name for the new class
- To extend our class from StatelessWidget.
- 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
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.
Let's understand the default flutter code.
This is where we import all the packages necessary for our flutter application.
import 'package:flutter/material.dart';
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());
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'),
);
}
}
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.
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.
Provides all the details about widgets available for UI development. It can be referred here.
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.
- Flutter Channel: https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw/about
- Tutorial by Smartherd: https://www.youtube.com/playlist?list=PLlxmoA0rQ-Lw6tAs2fGFuXGP13-dWdKsB
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
- 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'), ); ....
For Task 1 we expect you to use certain commonly used Widgets like rows, columns, Containers etc
Here we will be providing you with syntaxes and explanations of how these Widgets are used and exactly what do they represent.
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
...
],
)
);
}
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
]
),
),
);
}
}
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(
...
)
],
)
);
}
....
Here we will be learning about basic GET and POST requests, understanding APIs and using Postman.
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.
- GET
- POST
- PUT
- HEAD
- DELETE
- PATCH
- OPTIONS
We will be dealing only with GET and POST methods.
The GET methods are used to receive a response from a server or API.
The POST method is used to submit an entry to a server, which results in a change in state.
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:
- A request line.
- A series of HTTP headers, or header fields.
- A message body, if needed.
Read about HTTP requests in detail
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:
- A status line.
- A series of HTTP headers, or header fields.
- A message body, which is usually needed.
Read about HTTP responses in detail
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
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.
- Data is in name/value pairs
- Data is separated by commas
- Curly braces hold objects
- Square brackets hold an array
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
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:
- Tronald Dump: Ever wonder what Donald Trump thinks about something? This API can help.
- Chuck Norris Facts: A fan of Chuck Norris? This one is for you.
- Star Wars API: Create the ultimate Star Wars project for your portfolio!
- Pokemon API: All the Pokémon data you’ll ever need!
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
- When you open the documentation for the API and navigate to random quote, copy the request address.
- Then, open the Postman app and click on the '+' icon.
- Paste the link and click on the 'Send' button.
- The response can be seen in the body tab.
- The quote is the string associated with "value"
Similarly you can explore the documentation of other APIs and interact with them.
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.
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!')),
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.
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
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
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
You can see the full documentation for the Text class, here
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
You can see the full documentation of the Column class, here
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,
)
You can see the full documentation of the CircularProgressIndicator class, here
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,
)
],
),
The above code forms a stack of widgets as shown below:
You can see the documentation for the Stack class, here
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,
),
],
)
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.
You can see the full documentation of the ListView class, here
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 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
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
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 :