Flutter - Entendendo FutureBuilder - II


 Hoje vamos aplicar os conceitos de FutureBuilder obtendo e exibindo dados remotos.

O Flutter é um SDK de aplicativo móvel do Google que ajuda a criar aplicativos móveis modernos para iOS e Android usando uma única (quase) base de código.

Se você não conhece o Flutter veja o meu artigo :  Flutter - Primeiros contatos e impressões

Usando FutureBuilder na prática

Vamos continuar a primeira parte do artigo e mostrar um exemplo prático do FutureBuilder onde vamos obter os dados de uma API na web.

Vamos iniciar definindo o layout padrão usando o MaterialApp e o Scaffold usando um StatefulWidget:

import 'package:flutter/material.dart';
void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
    ),
  );
}
class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FutureBuilder")
       ),
       body: Text("teste") 
      );
    }
}
 

Precisamos definir uma fonte de dados remota que será acessada para retornar os dados que iremos exibir.

Vamos usar o serviço gratuito disponibilizado pelo site: https://jsonplaceholder.typicode.com/posts/

Que retorna dados no formato JSON que podemos usar.

Para acessar dados da internet vamos precisar usar o pacote http e realizar as seguintes taraefas:

  1. Incluir o pacote http no projeto
  2. Fazer uma requisição para uma url usando o pacote http
  3. converter a resposta obtida em um objeto Dart
  4. Tratar e exibir os dados no Flutter

Para instalar o pacote http, adicione-o à seção de dependências do arquivo pubspec.yaml. Você pode encontrar a versão mais recente do pacote http no site do Pub.


 dependencies:
   http: <latest_version>

Para fazer a requisição no site JSONPlaceholder vamos usar o método get do pacote http.


 Future<http.Response> getDataPost() {
     return http.get(url);
}

O método http.get() retorna um Future que contém uma resposta e a classe http.Response contém os dados recebidos de uma chamada http bem-sucedida.

A seguir precisamos converter a resposta obtida para um objeto Dart que no exemplo deve ser a classe Post cuja estrutura vemos a seguir:

class Post {
  final int userId;
  final int id;
  final String title;
  final String body;
  Post({this.userId, this.id, this.title, this.body});
  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
      body: json['body'],
    );
  }
}

Crie um arquivo chamado post.dart na pasta lib do projeto com o código acima.

Agora podemos converter o http.Response para um objeto Post e retornar um Future<Post>, para isso temos que :

  1. Converter o body do Response em um Mapa JSON com o pacote dart:convert.
  2. Se o servidor retornar uma resposta “OK” com um código de status de 200, temos que converter o Mapa JSON em um Post usando o método factory fromJson();
  3. Se o servidor retornar uma resposta inesperada, temos que enviar um erro;

Assim nossa função getDataPost() deve ficar assim:

Future<Post> getDataPost() async {

  final response =   await http.get(url);
  if (response.statusCode == 200) {
    return Post.fromJson(json.decode(response.body));
  } else {
    throw Exception('Falha ao carregar dados...');
  }
}

Temos então que incluir uma referência no projeto ao  dart:convert :  import 'dart:convert';

Finalmente basta agora tratar e exibir os dados.

Para buscar os dados e exibi-los na tela, vamos usar FutureBuilder fornecendo dois parâmetros:

  1. future - Representa os dados com que vamos tratar, no exemplo vamos usar getDataPost();
  2. builder - É uma função de construtor que informa ao Flutter o que processar, dependendo do estado do Future: carregamento, sucesso ou erro.
FutureBuilder<Post>(
  future: fetchPost(),
  builder: (context, snapshot) {

    if (snapshot.hasData) {
      return Text(snapshot.data.title);
    } else if (snapshot.hasError) {
      return Text("${snapshot.error}");
    }
    return CircularProgressIndicator();
  },
);

Aqui snapshot representa um instantâneo dos dados recebidos.

Assim o código completo do arquivo main.dart ficou assim:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_demo/post.dart';
import 'package:http/http.dart' as http;
const url = "https://jsonplaceholder.typicode.com/posts/1";
void main() async {
  runApp(MaterialApp(home: Home(),
  ));
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text("FutureBuilder")
       ),
       body: buildFutureBuilder()
      );
    }
  buildFutureBuilder() {
    return FutureBuilder<Post>(
       future : getDataPost(),
       builder: (context, snapshot) {
          switch(snapshot.connectionState){
            case ConnectionState.none :
            case ConnectionState.waiting:
            return Center(child: Text("Carregando..."));
             default: 
             if(snapshot.hasError){
               return Center(child: Text("Erro ao carregar..."),
                );
           } else {
             return Center(
               child: 
               Text('Id :' + snapshot.data.id.toString() + '\n\ntitulo : ' 
                             + snapshot.data.title ,
                              style : TextStyle(fontSize: 20.0) ));
           }
         }
       });
  }   
    Future<Post> getDataPost() async {

      final response =   await http.get(url);    
      if (response.statusCode == 200) {
          return Post.fromJson(json.decode(response.body));
      } else {
          throw Exception('Falha ao carregar dados...');
      }
    }
}

Estamos exibindo apenas o valor de title usando um widget Text centralizado.

Na próxima parte do artigo continuamos a tratar do FutureBuilder.

Pegue o codigo do arquivo main.dart main_futurebuild2.dart

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti