Flutter - Obtendos dados JSON e exibindo no ListView


Neste artigo vamos recordar como obter dados remotos no formato JSON e exibir no widget ListView do 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

Exibindo dados JSON no ListView

Este projeto Flutter é um exemplo básico de como podemos obter dados remotos no formato JSON e exibí-los em um widget ListView.

Vamos definir a nossa fonte de dados como sendo o serviço disponível em : https://jsonplaceholder.typicode.com

Vamos acessar os dados retornados pelo endpoint : https://jsonplaceholder.typicode.com/users que vemos a seguir:

Para isso vamos precisar incluir no arquivo pubspec.yaml a referência ao pacote http: ^0.12.0.0+2 conforme abaixo:

A seguir vamos criar na pasta lib o arquivo user.dart e neste arquivo definir a classe User que representa um usuário que iremos tratar.

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

Usaremos esta classe pare deserializar a lista de objetos obtida.

A seguir na pasta lib crie o arquivo api.dart e neste arquivo crie a classe API onde temos vamos obter os dados da url definida via método get do pacote http e retornar um Future:

import 'dart:async';
import 'package:http/http.dart' as http;
const baseUrl = "https://jsonplaceholder.typicode.com";
class API {
  static Future getUsers() {
     var url = baseUrl + "/users";
     return http.get(url);  
  }
}

O código define o método getUsers na classe API que retorna os dados dos usuários.

Vamos agora criar o código no arquivo main.dart para definir o leiaute básico usando os widgets MaterialApp:

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  build(context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Http-Json-ListView',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Text("Json-ListView"),
    );
  }
}
 

Agora vamos definir em home o widget BuildListView() que deverá ser um StatefulWidget.

Abaixo temos o código de BuildListView onde definimos uma lista de users do tipo List<User> e no body do Scaffold estamos usando um ListView.builder para exibir os dados do usuários obtidos:

class BuildListView extends StatefulWidget {
  @override
  createState() => _BuildListViewState();
}
class _BuildListViewState extends State {
  var users = new List<User>();  
  @override
  build(context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Lista de Usuários"),
        ),
        body: ListView.builder(
          itemCount: users.length,
          itemBuilder: (context, index) {
            return ListTile(title: Text(users[index].name));
          },
        ));
  }
}

Vamos precisar referenciar a classe User e a classe API.

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

import 'dart:convert';
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',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: BuildListView(),
    );
  }
}
class BuildListView extends StatefulWidget {
  @override
  createState() => _BuildListViewState();
}
class _BuildListViewState extends State {
  var users = new List<User>();
  _getUsers() {
    API.getUsers().then((response) {
      setState(() {
        Iterable list = json.decode(response.body);
        users = list.map((model) => User.fromJson(model)).toList();
      });
    });
  }
  initState() {
    super.initState();
    _getUsers();
  }
  dispose() {
    super.dispose();
  }
  @override
  build(context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Lista de Usuários"),
        ),
        body: ListView.builder(
          itemCount: users.length,
          itemBuilder: (context, index) {
            return ListTile(title: Text(users[index].name));
          },
        ));
  }
}

Estamos usando o método initState() para fazer uma chamada ao método _getUsers que invoca o método getUsers da API e define um setState que define uma lista de users que pode ser acessada sequencialmente.

O método initSate é o primeiro método chamado quando o widget é criado (após o construtor da classe, é claro).

O initState é chamado uma vez e somente uma vez e deve também chamar super.initState().

Usar este método é o indicado para :

- Inicializar os dados que dependem do BuildContext específico para a instância criada do widget.
- Inicializar as propriedades que dependem do 'pai' desses widgets na árvore.
- Assinar o Streams, ChangeNotifiers ou qualquer outro objeto que possa alterar os dados neste widget.

Pegue o código do arquivo main.dart aqui: main_json_listview.dart

"E esta é a mensagem que dele(Jesus) ouvimos, e vos anunciamos: que Deus é luz, e não há nele trevas nenhumas."
1 João 1:5

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