Mudanças entre as edições de "Flutter - Consumindo API"
(→Código) |
|||
(11 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
Linha 19: | Linha 19: | ||
== main.dart == | == main.dart == | ||
− | <syntaxhighlight lang=dart | + | <syntaxhighlight lang=dart> |
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||
import 'movies.dart'; | import 'movies.dart'; | ||
Linha 42: | Linha 42: | ||
O arquivo api.dart faz referência à API TVMaze e gerencia o objeto de transferência de um filme. | O arquivo api.dart faz referência à API TVMaze e gerencia o objeto de transferência de um filme. | ||
− | <syntaxhighlight lang=dart | + | <syntaxhighlight lang=dart> |
import 'package:http/http.dart' as http; | import 'package:http/http.dart' as http; | ||
Linha 80: | Linha 80: | ||
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. | 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. | ||
− | <syntaxhighlight lang=dart | + | <syntaxhighlight lang=dart> |
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||
import 'dart:convert'; | import 'dart:convert'; | ||
Linha 158: | Linha 158: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | == | + | == detail.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. | 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. | ||
− | <syntaxhighlight lang=dart | + | <syntaxhighlight lang=dart> |
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||
import 'package:url_launcher/url_launcher.dart'; | import 'package:url_launcher/url_launcher.dart'; | ||
Linha 173: | Linha 173: | ||
final Movie movie; | final Movie movie; | ||
− | DetailPage(this.movie); | + | const DetailPage(this.movie, {super.key}); |
@override | @override | ||
Linha 182: | Linha 182: | ||
), | ), | ||
body: Container( | body: Container( | ||
− | padding: | + | padding: const EdgeInsets.all(10.0), |
child: Column( | child: Column( | ||
children: [ | children: [ | ||
Linha 192: | Linha 192: | ||
), | ), | ||
), | ), | ||
− | Text("Link:"), | + | const Text("Link:"), |
// Aqui a gente coloca um link clicável. | // Aqui a gente coloca um link clicável. | ||
Linkify( | Linkify( | ||
onOpen: (link) async { | onOpen: (link) async { | ||
− | if (await | + | Uri link = Uri.parse(movie.link); |
− | await | + | if (await canLaunchUrl(link)) { |
+ | await launchUrl(link); | ||
} else { | } else { | ||
throw 'Não foi possível abrir {$movie.link}'; | throw 'Não foi possível abrir {$movie.link}'; | ||
Linha 216: | Linha 217: | ||
== Desafio 1 == | == 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 == | == Desafio 2 == | ||
− | Implemente uma aplicação que consuma alguma outra API de sua escolha. | + | * 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. |
Edição atual tal como às 13h51min de 10 de março de 2023
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.
import 'package:flutter/material.dart';
import 'dart:convert';
import 'api.dart';
import 'detail.dart';
// Vamos precisar de uma aplicação com estado
class MoviesListView extends StatefulWidget {
const MoviesListView({super.key});
@override
State<MoviesListView> createState() => _MoviesListViewState();
}
class _MoviesListViewState extends State<MoviesListView> {
List<Movie> movies = List<Movie>.empty(); // Lista dos filmes
String search = "star%20trek"; // Plavra chave da pesquisa
// Construtor, atualiza com setState a lista de filmes.
_MoviesListViewState() {
API.getMovie(search).then((response) {
setState(() {
Iterable lista = json.decode(response.body); // Usamos um iterator
movies = lista.map((model) => Movie.fromJson(model)).toList();
});
});
}
// Método build sobrecarregado que vai construir nossa página
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Lista de Filmes"),
),
// Aqui vem nossa lista
body: ListView.builder(
itemCount: movies.length, // quantidade de elementos
// Os elementos da lista
itemBuilder: (context, index) {
// Vai ser um item de lista tipo ListTile
return ListTile(
// Uma imagem de avatar redondinho com a imagem do filme
leading: CircleAvatar(
backgroundImage: NetworkImage(
movies[index].image,
),
),
// No título é o nome do filme
title: Text(
movies[index].name,
style: const TextStyle(
fontSize: 20.0,
color: Colors.black,
),
),
// No subtítulo colocamos o link
subtitle: Text(movies[index].link),
// Ação de clicar
onTap: () {
// Abrimos uma nova página, outra classe, que está no arquivo
// detail.dart. Veja que é um MaterialPageRote, tipo o
// MaterialApp, só que é só uma página nova.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(movies[index]),
),
);
},
);
},
),
);
}
}
detail.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.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'api.dart';
// Uma página para mostrar os detalhes de cada filme. Passamos o objeto
// do filme como parâmetro no constructor
class DetailPage extends StatelessWidget {
final Movie movie;
const DetailPage(this.movie, {super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(movie.name),
),
body: Container(
padding: const EdgeInsets.all(10.0),
child: Column(
children: [
Center(
child: Image(
image: NetworkImage(
movie.image,
),
),
),
const Text("Link:"),
// Aqui a gente coloca um link clicável.
Linkify(
onOpen: (link) async {
Uri link = Uri.parse(movie.link);
if (await canLaunchUrl(link)) {
await launchUrl(link);
} else {
throw 'Não foi possível abrir {$movie.link}';
}
},
text: movie.link,
),
],
),
),
);
}
}
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.