For this article i am assuming that you already have some idea about Flutter and its widgets . So if not please go to the below link and read more about it

So we will building a movie listing application using Flutter.

This application has two screens

Movie Listing Page Movie Details Page

We will start with the Movie Listing Page

When you create a new Flutter project you already have the main .dart file. We are going to create two more dart files in the same folder

movie_list.dart movie_details.dart

In your main.dart delete all the default code and start by importing the Flutter material package & the movie_list.dart file

Then lets add the main method in Flutter . The main method in any programming language is the method from which the compiler starts execution.

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

Here we are also calling our MyApp class . The MyApp class is a Stateless Widget and returns a MaterialApp Widget which is the root of our Application. The Material App widget has a title property which is the title of our app and a home property which tells us which widget will be seen when we open the app.

Right now if you run the app you will face an error because we haven’t added the MovieList class yet. So lets head over to our movie_list.dart file.

In this file we will be taking care of two major things

Hitting the OMDB Api, fetching the results and populating them in our UI Creating the list UI

So in our movie_list.dart file, we will start by making our MovieList class which will be a Stateful Widget (Again if you don’t know the difference between a Stateless Widget & a Stateful Widget please go through the docs once.). We are making the MovieList class as a Stateful Widget because when the API response is received we will be changing the state of the Widget.

class MovieList extends StatefulWidget {

@override

MovieListState createState() {

return new MovieListState();

}

}



class MovieListState extends State<MovieList> {





@override

Widget build(BuildContext context) {

} }

We will start building the top static section of our app that doesn’t change which is the Appbar and the ‘Top Rated’ heading.

So our MovieListState class needs to return a Widget. So we will be returning a Scaffold Widget.

Color mainColor = const Color(0xff3C3261);

Widget build(BuildContext context) {



return new Scaffold(

backgroundColor: Colors.white,

appBar: new AppBar(

elevation: 0.3,

centerTitle: true,

backgroundColor: Colors.white,

leading: new Icon(

Icons.arrow_back,

color: mainColor,

),

title: new Text(

'Movies',

style: new TextStyle(color: mainColor,fontFamily: 'Arvo',fontWeight: FontWeight.bold),

),

actions: <Widget>[

new Icon(

Icons.menu,

color: mainColor,

)

],

),

);

As you can see that our background color of our app screen is white. So we define a background color property with a color of white. Next for the appbar , the Scaffold Widget consist of an appBar property that lets us define an Appbar.

The Appbar has the following properties

elevation — Elevation of the AppBar centerTitle -Decides whether the Appbar title will be centered or aligned to the left backgroundColor — Background Color of the AppBar leading — This property is used to add widget at the start or left most side of the appbar. title - Title of the AppBar actions — This is a list of widgets that you want to add at the end or right most side of the appBar

We have added the back arrow and the hamburger menu icons to our appbar and set the title . We have also defined a variable called mainColor that we can use in any part of our widget wherever we want to add a purple color. If you run the app you should see the Appbar at the top.

Now moving to the heading ‘Top Rated’. The Scaffold has a body property which will contain all the widgets that we see like the heading and the list.

body: new Padding(

padding: const EdgeInsets.all(16.0),

child: new Column(

crossAxisAlignment: CrossAxisAlignment.start,

children: <Widget>[

new MovieTitle(mainColor),

],

),

),

Since the heading and list of movies are aligned vertically we are using a column widget. The column widget takes multiple widgets as its children. Inside the Column widget we are calling the MovieTitle widget that we are going to make next.

class MovieTitle extends StatelessWidget{



final Color mainColor;





MovieTitle(this.mainColor);



@override

Widget build(BuildContext context) {

return new Padding(

padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0),

child: new Text(

'Top Rated',

style: new TextStyle(

fontSize: 40.0,

color: mainColor,

fontWeight: FontWeight.bold,

fontFamily: 'Arvo'

),

textAlign: TextAlign.left,

),

);

}



}

The MovieTitle Widget takes the mainColor as an input parameter. Inside MovieTitle widget we have a text widget with the text and some text styling.

Let’s start with the next part of the app

Fetching the movies data Displaying the data in a list

In the movie_list.dart file first we need to import few packages

import 'dart:async';

import 'dart:convert';

import 'package:http/http.dart' as http;

These packages will help us in making asynchronous calls to the OMDB Api and return the required response to our widgets.

Future<Map> getJson() async {

var url =

'http://api.themoviedb.org/3/discover/movie?api_key={YOUR_OWN_API_KEY}';

http.Response response = await http.get(url);

return json.decode(response.body);

}

We are going to create a method with a return type Future. The reason to use future is that we don’t want our app to keep waiting for the response rather we want the app to make the api call and then let us know when the response is ready. Since the response is in JSON format we are using json.decode() to convert the format of the data from JSON to Map type.

In our MovieListState class we are going to use this method we just created to get the response and then use the response to update the ui.

class MovieListState extends State<MovieList> {



var movies;

Color mainColor = const Color(0xff3C3261);





void getData() async {

var data = await getJson();



setState(() {

movies = data['results'];

});

}

Since getJSON is an asynchronous method we need to define the getData method as async . Finally we will call the getData method inside our MovieListState build() method.

class MovieListState extends State<MovieList> {



var movies;

Color mainColor = const Color(0xff3C3261);





void getData() async {

var data = await getJson();



setState(() {

movies = data['results'];

});

}



@override

Widget build(BuildContext context) {

getData();

We have also created a variable called movies which will get the movie list data from the api response and we will use it to populate the list we are going to make next.

body: new Padding(

padding: const EdgeInsets.all(16.0),

child: new Column(

crossAxisAlignment: CrossAxisAlignment.start,

children: <Widget>[

new MovieTitle(mainColor),

new Expanded(

child: new ListView.builder(

itemCount: movies == null ? 0 : movies.length,

itemBuilder: (context, i) {

return new FlatButton(



child: new MovieCell(movies,i),

padding: const EdgeInsets.all(0.0),

color: Colors.white,

);



}),

)

],

),

),

So below the ‘Top Rating’ heading we are going to add a list of movies. For that we are going to use a ListView widget that will use the movies array to get data for individual rows of the list. We are going to wrap the ListView with a Expanded Widget so that the ListView takes up all the screen space left on the device (If you don’t do this you might not see the ListView a very common problem in Flutter).

The ListView widget has the following the properties

itemCount: — It is the number of items in our List itemBuilder — For each item of the array builds a new row and adds to the list

Since the api call is asynchronous initially the movies variable will be null and when the api returns the response then out setState will update the movies variable. The itemBuilder takes two arguments, one is the context and the other is the current iteration of the array. We are going to return a FlatButton because later we want to redirect to the movie details page on tapping the row. It has a child widget MovieCell which is the individual rows in our list and we are going to make that next.

class MovieCell extends StatelessWidget{



final movies;

final i;

Color mainColor = const Color(0xff3C3261);

var image_url = 'https://image.tmdb.org/t/p/w500/';

MovieCell(this.movies,this.i);



@override

Widget build(BuildContext context) {

return new Column(

children: <Widget>[

new Row(

children: <Widget>[

new Padding(

padding: const EdgeInsets.all(0.0),

child: new Container(

margin: const EdgeInsets.all(16.0),

child: new Container(

width: 70.0,

height: 70.0,

),

decoration: new BoxDecoration(

borderRadius: new BorderRadius.circular(10.0),

color: Colors.grey,

image: new DecorationImage(

image: new NetworkImage(

image_url + movies[i]['poster_path']),

fit: BoxFit.cover),

boxShadow: [

new BoxShadow(

color: mainColor,

blurRadius: 5.0,

offset: new Offset(2.0, 5.0))

],

),

),

),

new Expanded(



child: new Container(

margin: const EdgeInsets.fromLTRB(16.0,0.0,16.0,0.0),

child: new Column(children: [

new Text(

movies[i]['title'],

style: new TextStyle(

fontSize: 20.0,

fontFamily: 'Arvo',

fontWeight: FontWeight.bold,

color: mainColor),

),

new Padding(padding: const EdgeInsets.all(2.0)),

new Text(movies[i]['overview'],

maxLines: 3,

style: new TextStyle(

color: const Color(0xff8785A4),

fontFamily: 'Arvo'

),)

],

crossAxisAlignment: CrossAxisAlignment.start,),

)

),

],

),

new Container(

width: 300.0,

height: 0.5,

color: const Color(0xD2D2E1ff),

margin: const EdgeInsets.all(16.0),

)

],

);



}



}

The MovieCell widget takes two parameters in its constructor , one is the movies array and the other is the current iteration. We start with a column and our column will have two widgets : — One is the row which will contain our movie data and the other is the divider . For our movie data we will create a row with an Image on the left and the title and description on the right. The row will have two child widgets.

Now if you run the app you will get a list of movies with a amazing UI. In the part of this tutorial we will see how to go to the movie detail screen and create the ui of the movie detail page.

The source code of the complete app is available on github

Thanks for reading this article. Be sure to clap/recommend as much as you can and also share with your friends. It means a lot to me.

Also, Let’s become friends on Twitter, Linkedin and Github.