Aplikasi Mobile List Film dengan API dbMovie menggunakan Flutter

Pernahkah kamu ingin memesan tiket nonton di bioskop melalui aplikasi mobile seperti TIX, Traveloka, dan yang lainnya? Pada aplikasi tersebut terdapat list film bioskop secara lengkap dan up to date ya dari yang terbaru hingga yang lama.

Jika kita ingin membuat aplikasi sejenis, yaitu aplikasi untuk melihat daftar film yang sedang tayang atau akan tayang maka tutorial berikut sangat membantu dalam proses pembuatan aplikasi database movie tersebut.

Pertama-tama kita buat proyek flutter asumsi sudah tau ya cara buat proyek flutter pertama kali.

Nah sebelum kita berlanjut kedalam proses coding, mari kita persiapkan API key untuk/supaya kita bisa dapat mengakses data data yang disediakan oleh penyedia data film, nah disini kita akan menggunakan layanan dari themoviedb.org

Berikut merupakan tahap-tahap yang perlu dilakukan untuk mendapatkan API dan Hak aksesnya.

  1. Kunjungi situs themoviedb
themoviedb

2. Pilih menu signup untuk mendaftarkan akun, akun diperlukan untuk mendapatkan hak askses API.

Sign Up

3. Jika data sesuai dan dapat diterima berikutnya anda akan dialihkan pada halaman untuk cek email dan verifikasi akun yang sudah anda buat.

Email Verifikasi

Silahkan cek email dan verifikasi akun dengan mengklik Active My Account pada isi email verifikasi yang telah dirikim.

4. Silahkan login, dan setelahnya pilih menu API dan klik developers.themoviedb.org

API Page

5. Anda akan dialihkan kehalaman doc API, berikutnya silahkan click API link untuk proses registrasi API key.

API Link

6. Berikutnya klik generate API Key

API direct

7. Pilih Developer dan Accept pada halaman berikutnya.

Developer

8. Isi data saat create API untuk keperluan aplikasi dan data diri.

Details App

9. Finish, jika berhasil kita akan mendapatkan data akses API diantaranya adalah API key, Example API Request, API Read Access Token, seperti pada gambar berikut.

API Token

Setelah sudah kita dapatkan API Tokennya, berikutnya kita akan membuat code aplikasi menggunakan flutter di visual studio code.

1. Pada folder lib Projek Flutter buatlah folder baru bernama model dan data

2. Pada folder model kita akan membuat code data-data apa saja yang akan ditampilkan dan digunakan nantinya pada aplikasi.

Buatlah file dengan nama popular_movies.

class PopularMovies {
  int page;
  int totalResults;
  int totalPages;
  List<Results> results;

  PopularMovies({this.page, this.totalResults, this.totalPages, this.results});

  PopularMovies.fromJson(Map<String, dynamic> json) {
    page = json['page'];
    totalResults = json['total_results'];
    totalPages = json['total_pages'];
    if (json['results'] != null) {
      results = new List<Results>();
      json['results'].forEach((v) {
        results.add(new Results.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['page'] = this.page;
    data['total_results'] = this.totalResults;
    data['total_pages'] = this.totalPages;
    if (this.results != null) {
      data['results'] = this.results.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Results {
  double popularity;
  int voteCount;
  bool video;
  String posterPath;
  int id;
  bool adult;

  String backdropPath;
  String originalLanguage;
  String originalTitle;
  List<int> genreIds;
  String title;
  double voteAverage;
  String overview;
  String releaseDate;

  Results(
      {this.popularity,
      this.voteCount,
      this.video,
      this.posterPath,
      this.id,
      this.adult,
      this.backdropPath,
      this.originalLanguage,
      this.originalTitle,
      this.genreIds,
      this.title,
      this.voteAverage,
      this.overview,
      this.releaseDate});

  Results.fromJson(Map<String, dynamic> json) {
    popularity = json['popularity'];
    voteCount = json['vote_count'];
    video = json['video'];
    posterPath = json['poster_path'];
    id = json['id'];
    adult = json['adult'];
    backdropPath = json['backdrop_path'];
    originalLanguage = json['original_language'];
    originalTitle = json['original_title'];
    genreIds = json['genre_ids'].cast<int>();
    title = json['title'];
    voteAverage = json['vote_average'].toDouble();
    overview = json['overview'];
    releaseDate = json['release_date'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['popularity'] = this.popularity;
    data['vote_count'] = this.voteCount;
    data['video'] = this.video;
    data['poster_path'] = this.posterPath;
    data['id'] = this.id;
    data['adult'] = this.adult;
    data['backdrop_path'] = this.backdropPath;
    data['original_language'] = this.originalLanguage;
    data['original_title'] = this.originalTitle;
    data['genre_ids'] = this.genreIds;
    data['title'] = this.title;
    data['vote_average'] = this.voteAverage;
    data['overview'] = this.overview;
    data['release_date'] = this.releaseDate;
    return data;
  }
}

3. Berikutnya membuat file api_provider pada folder data di lib tadi yang berisikan konfigurasi authentikasi hak akses API yang sudah kita buat.

import 'dart:convert';

import 'package:app_movies/model/popular_movies.dart';
import 'package:http/http.dart'  show Client, Response;

class ApiProvider{
  String apiKey = '0fc5740199faa752da813c8c97f659e8';
  String baseUrl = 'https://api.themoviedb.org/3';

  Client client = Client();

  Future<PopularMovies> getPopularMovies() async{
   
  //  String url = '$baseUrl/movie/popular?api_key=$apiKey';
  //  print(url);
   Response response = await client.get('$baseUrl/movie/popular?api_key=$apiKey');
  
    if(response.statusCode == 200){
      return PopularMovies.fromJson(jsonDecode(response.body));
    } else {
      throw Exception(response.statusCode);
    }
  }
}

4. Kemudian membuat UI pada file main.dart buka file dan gunakan code berikut ini.

import 'package:app_movies/data/api_provider.dart';
import 'package:app_movies/model/popular_movies.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';

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

class MoviesApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Movies App',
      theme: ThemeData(
       primarySwatch: Colors.indigo, 
      ),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  ApiProvider apiProvider = ApiProvider();
  Future<PopularMovies> popularMovies;

  String imageBaseUrl = 'https://image.tmdb.org/t/p/w500';

  @override
  void initState() {
    popularMovies =  apiProvider.getPopularMovies();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Movies App'),
      ),
      body: FutureBuilder(
        future: popularMovies,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            print("Has Data: ${snapshot.hasData}");
            return ListView.builder(
              itemCount: snapshot.data.results.length,
              itemBuilder: (BuildContext context, int index) {
                return moviesItem(
                poster      : '$imageBaseUrl${snapshot.data.results[index].posterPath}',
                title       : '${snapshot.data.results[index].title}',
                date        : '${snapshot.data.results[index].releaseDate}',
                voteAverage : '${snapshot.data.results[index].voteAverage}',
                onTap: () {
                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) => MovieDetail(
                        movie: snapshot.data.results[index],
                      ))
                  );
                }
            );
              },
            );
          } else if (snapshot.hasError){
            print("Has Error: ${snapshot.hasError}");
            return Text('Error!!!');
          } else {
            print("Loading...");
            return CircularProgressIndicator();
          }
        },
      ),
    );
  }

  Widget moviesItem({String poster, String title, String date, String voteAverage, Function onTap}) {
    return InkWell(
      onTap: onTap,
          child: Container(
        margin: EdgeInsets.all(10),
        child: Card(
                child: Container(
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Container(
                        width: 120,
                        child: CachedNetworkImage(
                          imageUrl: poster,
                        ),
                      ),
                      SizedBox(
                        width: 20,
                      ),
                      Expanded(
                          child: Container(
                          margin: EdgeInsets.only(
                            top: 20
                          ),
                          child: Column(
                            crossAxisAlignment: 
                            CrossAxisAlignment.start,
                            mainAxisSize: MainAxisSize.min,
                            children: <Widget>[
                              Text(title, 
                                style: TextStyle(
                                  fontSize: 18,
                                  fontWeight: FontWeight.w600
                                  ),
                                ),
                              SizedBox(
                                height: 10,
                              ),
                              Row(
                                children: <Widget>[
                                  Icon(
                                    Icons.calendar_today, 
                                    size: 12,
                                  ),
                                  SizedBox(
                                    width: 5,
                                  ),
                                  Text(date),
                                ],
                              ),
                              SizedBox(
                                height: 10,
                              ),
                              Row(
                                children: <Widget>[
                                  Icon(
                                    Icons.star, 
                                    size: 12,
                                  ),
                                  SizedBox(
                                    width: 5,
                                  ),
                                  Text(voteAverage),
                                ],
                              ),
                            ],
                          ),
                        ),
                      )
                    ],
                  ),
          ),
        ),
      ),
    );
  }
}

class MovieDetail extends StatelessWidget {

  final Results movie;

  const MovieDetail({Key key, this.movie}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(movie.title),
      ),
      body: Container(
        child: Text(movie.overview),
      ),
    );
  }
}

5. Terakhir tambahkan library dengan menuliskan code pada file pubspec.yaml seperti berikut ini.

cached_network_image: 2.0.0-rc
http:

Selesai dan Debug/Run aplikasi, jika berhasil tampilan akan seperti berikut ini.

App View List Movie

Jika ada yang tidak dipahami dan perlu ditanyakan silahkan untuk ditanyakan. Tulis di kolom komentar ya. Berikut Source Code lengkapnya. clone App dbMovie

Leave a Reply

Your email address will not be published. Required fields are marked *

× Mau Merchandise? bisa, Chat WA yak