Flutter - Consumindo API
Afluentes: Dispositivos Móveis; Usabilidade, desenvolvimento web, mobile e jogos
Pré-requisitos
Primeiro vamos criar nosso projeto e incluir alguns pacotes, então digite na pasta do projeto:
flutter create movies cd movies flutter pub add url_launcher flutter pub add flutter_linkify flutter pub add http
Código
O Aplicativo faz uma requisição de filmes em uma API. Tal como fizemos no Consumindo API com React.js, só que agora em Flutter.
O arquivo main.dart é simples e ele só inicia a página principal.
main.dart
1import 'package:flutter/material.dart';
2import 'movies.dart';
3
4void main() => runApp(App());
5
6class App extends StatelessWidget {
7 @override
8 build(context) {
9 return MaterialApp(
10 title: 'Filmes',
11 home: MoviesListView(),
12 );
13 }
14}
api.dart
O arquivo api.dart faz referência à API TVMaze e gerencia o objeto de transferência de um filme.
1import 'package:http/http.dart' as http;
2
3// A URL da API
4const baseUrl = "https://api.tvmaze.com/search/shows?q=";
5
6// Criamos a classe da nossa API. O nome você que escolhe. Fazemos aqui
7// uma requisição get (como fizemos no react) e passamos a URL, mas usamos
8// um Uri.parse pra transformar a string em uma URI.
9class API {
10 static Future getMovie(search) async {
11 var url = baseUrl + search;
12 return await http.get(Uri.parse(url));
13 }
14}
15
16// Criamos uma classe para representar os objetos que vão conter os filmes
17// e colocamos só os campos que vamos usar.
18class Movie {
19 int id;
20 String name;
21 String link;
22 String image;
23
24 Movie(int id, String name, String link, String image) {
25 this.id = id;
26 this.name = name;
27 this.link = link;
28 this.image = image;
29 }
30
31 Movie.fromJson(Map json)
32 : id = json['show']['id'],
33 name = json['show']['name'],
34 link = json['show']['url'],
35 image = json['show']['image']['medium'];
36}
movies.dart
O arquivo movie.dart conteém a lista de filmes no formato JSON que ele vai trazer da API e cria uma LIST com objetos do tipo Movie criado no arquivo api.dart.
1import 'package:flutter/material.dart';
2import 'dart:convert';
3import 'api.dart';
4import 'detail.dart';
5
6// Vamos precisar de uma aplicação com estado
7class MoviesListView extends StatefulWidget {
8 @override
9 _MoviesListViewState createState() => _MoviesListViewState();
10}
11
12class _MoviesListViewState extends State<MoviesListView> {
13 List<Movie> movies = List<Movie>.empty(); // Lista dos filmes
14 String search = "star%20trek"; // Plavra chave da pesquisa
15
16 // Construtor, atualiza com setState a lista de filmes.
17 _MoviesListViewState() {
18 API.getMovie(search).then((response) {
19 setState(() {
20 Iterable lista = json.decode(response.body); // Usamos um iterator
21 movies = lista.map((model) => Movie.fromJson(model)).toList();
22 });
23 });
24 }
25
26 // Método build sobrecarregado que vai construir nossa página
27 @override
28 Widget build(BuildContext context) {
29 return Scaffold(
30 appBar: AppBar(
31 title: Text("Lista de Filmes"),
32 ),
33 // Aqui vem nossa lista
34 body: ListView.builder(
35 itemCount: movies.length, // quantidade de elementos
36 // Os elementos da lista
37 itemBuilder: (context, index) {
38 // Vai ser um item de lista tipo ListTile
39 return ListTile(
40 // Uma imagem de avatar redondinho com a imagem do filme
41 leading: CircleAvatar(
42 backgroundImage: NetworkImage(
43 movies[index].image,
44 ),
45 ),
46 // No título é o nome do filme
47 title: Text(
48 movies[index].name,
49 style: TextStyle(fontSize: 20.0, color: Colors.black),
50 ),
51 // No subtítulo colocamos o link
52 subtitle: Text(movies[index].link),
53 // Ação de clicar
54 onTap: () {
55 // Abrimos uma nova página, outra classe, que está no arquivo
56 // detail.dart. Veja que é um MaterialPageRote, tipo o
57 // MaterialApp, só que é só uma página nova.
58 Navigator.push(
59 context,
60 new MaterialPageRoute(
61 builder: (context) => DetailPage(movies[index]),
62 ),
63 );
64 },
65 );
66 },
67 ),
68 );
69 }
70}
details.dart
Esse arquivo contém a página que é chamada para mostrar detalhes de um filme depois que você clicar nele na lista de filmes de movies.dart.
1import 'package:flutter/material.dart';
2import 'package:url_launcher/url_launcher.dart';
3import 'package:flutter_linkify/flutter_linkify.dart';
4import 'api.dart';
5
6// Uma página para mostrar os detalhes de cada filme. Passamos o objeto
7// do filme como parâmetro no constructor
8class DetailPage extends StatelessWidget {
9 final Movie movie;
10
11 DetailPage(this.movie);
12
13 @override
14 Widget build(BuildContext context) {
15 return Scaffold(
16 appBar: AppBar(
17 title: Text(movie.name),
18 ),
19 body: Container(
20 padding: new EdgeInsets.all(10.0),
21 child: Column(
22 children: [
23 Center(
24 child: Image(
25 image: NetworkImage(
26 movie.image,
27 ),
28 ),
29 ),
30 Text("Link:"),
31 // Aqui a gente coloca um link clicável.
32 Linkify(
33 onOpen: (link) async {
34 if (await canLaunch(movie.link)) {
35 await launch(movie.link);
36 } else {
37 throw 'Não foi possível abrir {$movie.link}';
38 }
39 },
40 text: movie.link,
41 ),
42 ],
43 ),
44 ),
45 );
46 }
47}
Atividades
Desafio 1
1. Implemente o exemplo anterior em seu comptuador.
Desafio 2
Implemente uma aplicação que consuma alguma outra API de sua escolha.