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
import 'package:flutter/material.dart';
import 'movies.dart';
void main() => runApp(const App());
class App extends StatelessWidget {
const App({super.key});
@override
build(context) {
return const MaterialApp(
title: 'Filmes',
home: MoviesListView(),
);
}
}
api.dart
O arquivo api.dart faz referência à API TVMaze e gerencia o objeto de transferência de um filme.
import 'package:http/http.dart' as http;
// A URL da API
const baseUrl = "https://api.tvmaze.com/search/shows?q=";
// Criamos a classe da nossa API. O nome você que escolhe. Fazemos aqui
// uma requisição get (como fizemos no react) e passamos a URL, mas usamos
// um Uri.parse pra transformar a string em uma URI.
class API {
static Future getMovie(search) async {
var url = baseUrl + search;
return await http.get(Uri.parse(url));
}
}
// Criamos uma classe para representar os objetos que vão conter os filmes
// e colocamos só os campos que vamos usar.
class Movie {
int id;
String name;
String link;
String image;
Movie(this.id, this.name, this.link, this.image);
Movie.fromJson(Map json)
: id = json['show']['id'],
name = json['show']['name'],
link = json['show']['url'],
image = json['show']['image']['medium'];
}
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 const MoviesListView({super.key});
9
10 @override
11 State<MoviesListView> createState() => _MoviesListViewState();
12}
13
14class _MoviesListViewState extends State<MoviesListView> {
15 List<Movie> movies = List<Movie>.empty(); // Lista dos filmes
16 String search = "star%20trek"; // Plavra chave da pesquisa
17
18 // Construtor, atualiza com setState a lista de filmes.
19 _MoviesListViewState() {
20 API.getMovie(search).then((response) {
21 setState(() {
22 Iterable lista = json.decode(response.body); // Usamos um iterator
23 movies = lista.map((model) => Movie.fromJson(model)).toList();
24 });
25 });
26 }
27
28 // Método build sobrecarregado que vai construir nossa página
29 @override
30 Widget build(BuildContext context) {
31 return Scaffold(
32 appBar: AppBar(
33 title: const Text("Lista de Filmes"),
34 ),
35 // Aqui vem nossa lista
36 body: ListView.builder(
37 itemCount: movies.length, // quantidade de elementos
38 // Os elementos da lista
39 itemBuilder: (context, index) {
40 // Vai ser um item de lista tipo ListTile
41 return ListTile(
42 // Uma imagem de avatar redondinho com a imagem do filme
43 leading: CircleAvatar(
44 backgroundImage: NetworkImage(
45 movies[index].image,
46 ),
47 ),
48 // No título é o nome do filme
49 title: Text(
50 movies[index].name,
51 style: const TextStyle(
52 fontSize: 20.0,
53 color: Colors.black,
54 ),
55 ),
56 // No subtítulo colocamos o link
57 subtitle: Text(movies[index].link),
58 // Ação de clicar
59 onTap: () {
60 // Abrimos uma nova página, outra classe, que está no arquivo
61 // detail.dart. Veja que é um MaterialPageRote, tipo o
62 // MaterialApp, só que é só uma página nova.
63 Navigator.push(
64 context,
65 MaterialPageRoute(
66 builder: (context) => DetailPage(movies[index]),
67 ),
68 );
69 },
70 );
71 },
72 ),
73 );
74 }
75}
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:movies/details.dart';
3import 'dart:convert';
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 MoviesListView extends StatefulWidget {
9 const MoviesListView({super.key});
10
11 @override
12 State<StatefulWidget> createState() => _MoviesListViewState();
13}
14
15class _MoviesListViewState extends State<MoviesListView> {
16 List<Movie> movies = List<Movie>.empty();
17 String search = "attack on titan";
18
19 _MoviesListViewState() {
20 API.getMovie(search).then((response) {
21 setState(() {
22 Iterable list = json.decode(response.body);
23 movies = list.map((model) => Movie.fromJson(model)).toList();
24 });
25 });
26 }
27
28 @override
29 Widget build(BuildContext context) {
30 return Scaffold(
31 appBar: AppBar(
32 title: const Text('Lista de Filmes'),
33 ),
34 body: ListView.builder(
35 itemCount: movies.length,
36 itemBuilder: (context, index) {
37 return ListTile(
38 leading: CircleAvatar(
39 backgroundImage: NetworkImage(
40 movies[index].image,
41 ),
42 ),
43 title: Text(
44 movies[index].name,
45 style: const TextStyle(
46 fontSize: 20.0,
47 color: Colors.black,
48 ),
49 ),
50 subtitle: Text(movies[index].url),
51 onTap: () {
52 Navigator.push(
53 context,
54 MaterialPageRoute(
55 builder: (context) => DetailPage(movies[index]),
56 ),
57 );
58 },
59 );
60 },
61 ),
62 );
63 }
64}
Atividades
Desafio 1
- Implemente o exemplo anterior em seu computador.
- Adicione um campo texto e um botão "Procurar". Quando clicar no botão procurar, atualiza a lista de filmes conforme a string do campo texto.
Desafio 2
- Implemente uma aplicação que consuma alguma outra API de sua escolha.
- Se você já estiver trabalhando com criação de microsserviços web na disciplina de Sistemas Distribuídos, você pode criar uma API pra consumir no flutter.