Mudanças entre as edições de "Flutter - Consumindo API"
(→Código) |
|||
(7 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: | + | import 'package:url_launcher/url_launcher.dart'; |
− | import 'dart | + | import 'package:flutter_linkify/flutter_linkify.dart'; |
import 'api.dart'; | import 'api.dart'; | ||
// Uma página para mostrar os detalhes de cada filme. Passamos o objeto | // Uma página para mostrar os detalhes de cada filme. Passamos o objeto | ||
// do filme como parâmetro no constructor | // do filme como parâmetro no constructor | ||
− | class | + | class DetailPage extends StatelessWidget { |
− | + | final Movie movie; | |
− | |||
− | |||
− | |||
− | |||
− | + | const DetailPage(this.movie, {super.key}); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
@override | @override | ||
Linha 194: | Linha 179: | ||
return Scaffold( | return Scaffold( | ||
appBar: AppBar( | appBar: AppBar( | ||
− | title: | + | title: Text(movie.name), |
), | ), | ||
− | body: | + | 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, | ||
), | ), | ||
− | + | ], | |
− | + | ), | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
), | ), | ||
); | ); | ||
Linha 233: | 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. 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. | + | * 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.