Flutter - Lista básica com ListView - III


Hoje vamos continuar a apresentar como exibir uma lista de dados usando Flutter.

Continuando a segunda parte do artigo hoje usaremos como exemplo o construtor ListView.builder para exibir uma grande quantidade de itens na lista de itens.

Para exibir uma lista de itens com uma grande quantidade de itens podemos usar o construtor ListView.builder.

A principal diferença entre ListView e ListView.builder é que o construtor ListView padrão requer que criemos todos os itens de uma só vez, enquanto o construtor ListView.builder criará itens à medida que eles forem rolados para a tela, como por demanda.

Criando um novo projeto Flutter

No VS Code abra a paleta de comandos (ctrl+shift+p) e digite flutter;

A seguir clique em New Project, informe o nome listviewbuilder e escolha a pasta onde o projeto será criado.

Como vamos exibir uma imagem local - planeta1.jpg - em nossa aplicação precisamos criar uma pasta assets na raiz do projeto e copiar a imagem que vamos exibir para esta pasta.(voce pode usar qualquer nome de pasta)

Para poder exibir a imagem em nossa aplicação Flutter precisamos adicionar o nome desta imagem dentro do arquivo pubspec.yaml.

Adicione a seguinte linha de código dentro do arquivo pubspec.yaml.

Ao final nosso projeto terá a seguinte estrutura:

Criando o Stateful Widgets

No Flutter tudo são Widgets, e, podemos ter dois tipos de widgets: Stateless e Statefull, ou seja, sem estado e com estado.

Neste exemplo vamos criar um Stateful Widget, ou seja, um widget dinâmico que vai poder ser alterado por uma ação do usuário.

Substitua o código do arquivo main.dart pelo código abaixo:

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}
class _MyAppState extends State<MyApp> {
  List<String> _planetas = ['Saturno'];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.deepPurple),
      home: Scaffold(
        appBar: AppBar(title: Text('Lista de Planetasa')),
        body: Column(children: [
          Container(
              margin: EdgeInsets.all(10.0),
              child: RaisedButton(
                  color: Theme.of(context).primaryColor,
                  splashColor: Colors.blueGrey,
                  textColor: Colors.white,
                  onPressed: () {
                    setState(() {
                      _planetas.add('Saturno');
                    });
                  },
                  child: Text('Adicionar Planetas'))),
          Column(
              children: _planetas
                  .map((element) => Card(
                        child: Column(
                          children: <Widget>[
                            Image.asset('assets/planeta1.jpg'),
                            Text(element,
                                style: TextStyle(color: Colors.deepPurple))
                          ],
                        ),
                      ))
                  .toList()),
        ]),
      ),
    );
  }
}

Neste código criamos um widget com estado e, em seguida, configuramos o tema para o aplicativo flutter. Em seguida, pegamos um botão criado e, quando o usuário pressiona o botão, adicionamos a imagem ao array e exibimos a imagem com o widget de Card.

Dessa forma estamos exibindo dois itens: Image e Text.

Para executar podemos pressionar F5 ou no terminal de comandos, estando posicionado na pasta do projeto, basta digitar :  flutter run -d all

Executando o projeto iremos obter o resultado abaixo:

Ao clicar no botão para - Adicionar Planetas - veremos uma mensagem alertando que houve um overflow indicando que a imagem incluida passou os limites de exibição.

Resolvendo o problema

Para resolver este problema temos que criar uma lista rolável usando o widget ListView.builder.

O construtor ListView.builder() é apropriado para exibições de lista com um número grande (ou infinito) de filhos, porque o construtor é chamado apenas para aqueles filhos visíveis.

Vamos fornecer um itemCount não nulo para melhorar a capacidade do ListView de estimar a extensão máxima de rolagem.

O retorno de chamada itemBuilder será chamado apenas com índices maiores ou iguais a zero e menores que itemCount.

Para fazer esta implementação vamos dividir o nosso projeto em dois arquivos:

  1. planetas.dart
  2. main.dart

O arquivo planetas.dart será responsável apenas por exibir os itens no widget Card com a ajuda do widget de construtor ListView.builder.

Inclua um novo arquivo chamado planetas.dart na pasta lib e a seguir inclua o código abaixo:

import 'package:flutter/material.dart';
class Planetas extends StatelessWidget {
  final List<String> planetas;
  Planetas(this.planetas);
  Widget _buildPlanetaItem(BuildContext context, int index) {
    return Card(
      child: Column(
        children: <Widget>[
          Image.asset('assets/planeta1.jpg'),
          Text(planetas[index], style: TextStyle(color: Colors.deepPurple))
        ],
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: _buildPlanetaItem,
      itemCount: planetas.length,
    );
  }
}

Esse código representa a classe Planetas que possui um método chamado _buildPlanetaItem que retorna o widget ListView.builder.

O widget ListView.builder usa dois argumentos.

A seguir vamos alterar o código do arquivo main.dart conforme abaixo:

import 'package:flutter/material.dart';
import './planetas.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}
class _MyAppState extends State<MyApp> {
  List<String> _planetas = [];
  @override
  void initState() {
    super.initState();
    _planetas.add('Saturno');
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: ThemeData(primarySwatch: Colors.deepPurple),
        home: Scaffold(
            appBar: AppBar(title: Text('Lista de Planetas')),
            body: Column(children: [
              Container(
                  margin: EdgeInsets.all(10.0),
                  child: RaisedButton(
                      color: Theme.of(context).primaryColor,
                      splashColor: Colors.blueGrey,
                      textColor: Colors.white,
                      onPressed: () {
                        setState(() {
                          _planetas.add('Saturno');
                        });
                      },
                      child: Text('Saturno'))),
              Expanded(child: Planetas(_planetas))
            ])));
  }
}

Aqui, usamos o widget Expanded que permite expandir um filho de uma Linha, Coluna ou Flex.

O uso de um widget Expanded faz com que o filho de uma Linha, Coluna ou Flex se expanda para preencher o espaço disponível no eixo primário (por exemplo, horizontalmente para uma linha ou verticalmente para uma coluna). Se vários filhos são expandidos, um espaço disponível é dividido entre eles de acordo com o fator flex.

Aqui, passamos o construtor de planetas importado com o argumento da matriz _planetas.

Agora executando novamente ou apenas dando o hot reload, incluindo mais dois itens na lista iremos ver o seguinte resultado :

Vemos agora que a lista vai exibindo os itens conforme vão sendo incluídos.

Esta é a maneira mais eficiente de exibir uma lista longa com o ListView, usando o construtor ListView.builder().

Na próxima parte do artigo veremos como obter dados de uma API REST no formato JSON via HTTP e exibir em um ListView.

E a paz de Deus, que excede todo o entendimento, guardará os vossos corações e os vossos pensamentos em Cristo Jesus. Filipenses 4:7

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