1
resposta

Adicionar itens em uma ListView usando FloatingActionButton com setState

Olá, estou com dificuldades para fazer o meu app atualizar uma ListView ao clicar no botão do tipo FloatingActionButton.

Alguém pode me dar uma ajuda nisso. O código está funcionando só falta ajustar isso.

valeu.

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:barcode_scan/barcode_scan.dart';

/// Description : App root
/// @Author     : Tiago dos Santos
/// since       : 2020/01/26
/// 
/// sample: https://pub.dev/packages/barcode_scan#-example-tab-
/// https://github.com/apptreesoftware/flutter_barcode_reader/blob/master/example/lib/main.dart
/// 
void main() => runApp(TMSMobileApp());

///
/// Class Main Screen
/// @Author : Tiago dos Santos
/// @Since  : 27/01/2020
/// 
class TMSMobileApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return  MaterialApp(
        home: ListaDeCarregamento(),);
  }
}

///
///
///
class ListaDeCarregamento extends StatefulWidget{

  StreamController<CargoLoader> _listCargoController = StreamController<CargoLoader>();

  ListaDeCarregamento({Key key}): super(key:key);
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _ListaDeCarregamentoState();
  }
}

///
///
/// state controller of main App to update listview
///
///
class _ListaDeCarregamentoState extends State<ListaDeCarregamento>{

  CargoLoader cargoData;

  void _updateData(String barcode,String description,String invoice){
    setState(() {
      cargoData = CargoLoader(description,invoice,barcode);
    });
  }

  Future<String> _barcodeScan() async {
        String barcode;
        try{
            barcode = await BarcodeScanner.scan();
            return barcode;
        }on PlatformException{
            debugPrint('calling scan...failed');
            return "";
        }
  }

  @override
  Widget build(BuildContext context) {

    // TODO: implement build
    return Scaffold(
      body: ListOfLoaders(),
      appBar: AppBar(title: Text('Carregamento de Carga'),),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.photo_camera), 
        onPressed: () async {
                final String barcode = await _barcodeScan();
                debugPrint('readed this code $barcode');
                _updateData('descr.1','invoice number', barcode);
                ListOfLoaders()._listCargoLoad.add(cargoData);

            }),
      );
  }
}


///
/// Classe responsável por exibir um widget de Lista de carregamento
/// @Author : Tiago dos Santos
/// since   : 2020/01/26
///
class ListOfLoaders extends StatefulWidget{
  final List<CargoLoader> _listCargoLoad = List();

  @override
  State<StatefulWidget> createState() {
      return ListOfLoaderState();
  }
}

class ListOfLoaderState extends State<ListOfLoaders>{
@override
  Widget build(BuildContext context){
    return ListView.builder(
        itemCount: widget._listCargoLoad.length,
        itemBuilder: (context,index){
          final cargoLoader = widget._listCargoLoad[index];
          return ItemLoader(cargoLoader);
        },
    );
  }  
}

///
/// Classe responsável por adicionar um card
/// Widget card para a lista de carregamento.
/// @Author : Tiago dos Santos
/// since   : 2020/01/26
///
class ItemLoader extends StatelessWidget{

  final CargoLoader _cargoLoader;

  ItemLoader(this._cargoLoader);

  @override
  Widget build(BuildContext context){
    return Card(
      child: ListTile(
                leading: Icon(Icons.account_box),
                title: Text(_cargoLoader.description),
                subtitle: Text(_cargoLoader.invoice),
                trailing: IconButton(
                                icon: Icon(Icons.delete),
                                onPressed:(){
                                   onDeleteAction();
                                }
                          ),
            ),
      );
  }

  void onDeleteAction(){
    debugPrint("teste");
  }
}

///
/// Estrutura de dados de carregamento
/// @Author : Tiago dos Santos
/// since   : 2020/01/26
/// 
class CargoLoader{
  final String description;
  final String invoice;
  final String barCode;
  CargoLoader(this.description, this.invoice, this.barCode);
}
1 resposta

Oi Tiago, tudo bem?

Muito provavelmente o seu problema está no código de adição do

// TODO: implement build
return Scaffold(
    // está enviando essa referência
    body: ListOfLoaders(),
    appBar: AppBar(title: Text('Carregamento de Carga'),),
    floatingActionButton: FloatingActionButton(
    child: Icon(Icons.photo_camera), 
    onPressed: () async {
            final String barcode = await _barcodeScan();
            debugPrint('readed this code $barcode');
            _updateData('descr.1','invoice number', barcode);
            //está tentando atualizar outra referência
            ListOfLoaders()._listCargoLoad.add(cargoData);

        }),
    );
}

Observe que nos meus comentários você envia uma referência de ListOfLoaders no body e no onPressed cria uma nova e tenta atualizá-la. Para resolver esse problema, você precisa criar o objeto de ListOfLoaders, enviá-lo para o body e utilizá-lo para adicionar na lista.

O outro passo é criar um método em ListOfLoaders que recebe um cargoData e fica responsável em adicionar na lista e chamar o setState para atualizar o conteúdo visual do Widget.

[]s