Flutter - Obtendo dados da Web e exibindo no ListView


Hoje veremos como podemos obter dados da internet e exibí-los em um ListView no Flutter.

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

Obtendos dados da internet

Eu já tratei como exibir dados da internet no Flutter neste artigo : Flutter - Obtendo dados da Web (REST)

Assim, neste artigo eu vou apenas mostrar o código usado no projeto seguindo o roteiro definido neste artigo, portanto já temos o pacote http definido no arquivo pubspec.yaml na seção dependencies.

Neste projeto vamos exibir os dados do serviço disponibilizado em : https://jsonplaceholder.typicode.com/users

Abaixo temos o retorno deste endpoint:

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  }, 
...

Para simplificar o artigo eu vou tratar apenas as informações de : id, name, username e email.

Assim a primeira coisa que vamos fazer é criar uma classe chamada API onde vamos definir o método que vai acessar a url usando o método get do pacote http:

Crie o arquivo api.dart na pasta lib e a seguir inclua o código abaixo neste arquivo:

import 'package:http/http.dart' as http;
const baseUrl = "https://jsonplaceholder.typicode.com";

class API {
    static Future getUsers() async{
        var url = baseUrl + "/users";
        return await http.get(url);
    }
}

No código importamos o pacote http, definimos a url e criamos o método getUsers na classe API que retorna um Future e portanto é um método assíncrono que usa o método get para acessar os dados da url.

Os dados serão obtido no formato JSON e para poder acessar de forma mais fácil as informações eu vou criar um objeto do tipo dos dados retornados que são dados de usuários. Assim vou criar uma classe User com as propriedades id, name, username e email, que são as informações retornadas.

Podemos gerar a classe User a partir dos dados JSON usando este site: https://javiercbk.github.io/json_to_dart/

Apenas copiamos os dados JSON que desejamos tratar, definimos o nome User e temos a classe User e o método FromJson(), que mapeia os dados JSON para um objeto User, definidos na classe User. O método toJson() faz o processo inverso e não vamos precisar dele em nosso projeto.

Assim vamos criar a classe User no projeto copiando o código gerado. Crie o arquivo user.dart na pasta lib e inclua o código abaixo neste arquivo:

class User {
  int id;
  String name;
  String username;
  String email;
  User(int id, String name, String username, String email) {
    this.id = id;
    this.name = name;
    this.username = username;
    this.email = email;
  }
  User.fromJson(Map json)
      : id = json['id'],
        name = json['name'],
        username = json['username'],
        email = json['email'];
}

Temos assim a classe User que iremos usar para obter objetos do tipo User a partir dos dados JSON.

Definindo a interface

Vamos definir o código no arquivo main.dart definindo inicialmente o leiaute básico usando o MaterialApp e o Scaffold ;

import 'package:flutter/material.dart';
import 'package:flutter_demos/user.dart';
import 'api.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  build(context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Http-Json-ListView',
      home: BuildListView(),
    );
  }
}
class BuildListView extends StatefulWidget {
  @override
  _BuildListViewState createState() => _BuildListViewState();
}
class _BuildListViewState extends State<BuildListView> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar : AppBar( 
        title: Text("Lista de Usuários"),
      ),
      body: listaUsuarios()
    );
  }  
  listaUsuarios() {
  }
}

Neste código temos o leiaute básico onde criamos um Statefullwidget chamado BuildListView que iremos usar para criar o ListView onde vamos exibir os dados obtidos do serviço REST.

No body do Scaffold vamos criar o método listaUsuarios() onde vamos acessar os dados JSON, converter os dados para objetos User e exibir os dados no ListView.

Vamos fazer isso na classe _BuildListViewState :

class _BuildListViewState extends State<BuildListView> {
   var users = new List<User>();
   _getUsers(){
     API.getUsers().then((response){
       setState(() {
          Iterable lista = json.decode(response.body);
          users = lista.map((model) => User.fromJson(model)).toList();
       });
     });
   }
   _BuildListViewState() {
     _getUsers();
   }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar : AppBar( 
        title: Text("Lista de Usuários"),
      ),
      body: listaUsuarios()
    );
  }  
  listaUsuarios() {
    }
}

Neste código criamos:

1- Uma lista de users do tipo User que vai conter dos dados que vamos exibir:  var users = new List<User>();

2- O método _getUsers() onde usamos o método getUsers() da classe API e usamos o método then do Future para tratar os dados retornados que já estão disponíveis.

Criamos uma lista do tipo Iterable que pode ser acessada sequencialmente a partir dos dados JSON obtidos do response.body da classe API.

A seguir usamos o método fromJson() da classe User para converter os dados para objetos do tipo User gerando a lista de objetos User.

3- No construtor da classe chamamos o método _getUsers:

_BuildListViewState() {
     _getUsers();
   }


Podemos agora criar o ListView usando o construtor ListView.builder e exibir os dados no método listaUsuarios():

listaUsuarios() {
    return ListView.builder(
      itemCount : users.length,
      itemBuilder: (context, index) {

         return ListTile(
           leading: CircleAvatar(
             backgroundImage: NetworkImage( 'http://www.macoratti.net/Imagens/contato1.png'),),
           title: Text(users[index].name, style: TextStyle(fontSize: 20.0, color: Colors.black)),
           subtitle: Text(users[index].email),
        );

      },
     );
  }

Definimos o ItemCount como o tamanho da lista users, e a seguir usamos um ListTile onde definimos :

1- no parâmetro leading um CircleAvatar para exibir uma imagem arredondada obtida do endereço :'http://www.macoratti.net/Imagens/contato1.png' ;

2- no parâmetro title um widget Text exibindo o nome do usuário (users[index].name) aplicando um estilo com fonte de tamanho 20.0 e cor negra;

3- no parâmetro subtitle um widget Text exibindo o email do usuário : users[index].email;

Executando o projeto iremos obter o resultado abaixo:

Nada mal...

E se quisermos exibir os detalhes de um usuário quando alguém clicar sobre um item da lista ?

Veremos isso na próxima parte do artigo.

Pegue o projeto dos arquivos api.dart, user.dart e main.dart aqui: main_user_api.dart

"Dando graças ao Pai que nos fez idôneos para participar da herança dos santos na luz;
O qual nos tirou da potestade das trevas, e nos transportou para o reino do Filho do seu amor;
Em quem temos a redenção pelo seu sangue, a saber, a remissão dos pecados;
O qual é imagem do Deus invisível, o primogênito de toda a criação;"
Colossenses 1:12-15

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