Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Quando clico no botão confirmar meus dados de transferencia e valor não aparecem na tela da Lista transferencias

meu código:

import 'package:flutter/material.dart';

void main() => runApp(BytebankApp());

class BytebankApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ListaTransferencias(),
      ),
    );
  }
}

class FormularioTrasferencia extends StatelessWidget {
  final TextEditingController _controladorCampoNumeroConta =
  TextEditingController();
  final TextEditingController _controladorCampoValor = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Criando Transferência"),
      ),
      body: Column(
        children: <Widget>[
          Editor(
              controlador: _controladorCampoNumeroConta,
              rotulo: "Número da conta",
              dica: "0000",
              icone: Icons.account_balance_sharp),
          Editor(
              controlador: _controladorCampoValor,
              rotulo: "Valor",
              dica: "0,00",
              icone: Icons.monetization_on),
          ElevatedButton(
            child: Text('Confirmar'),
            onPressed: () => _criaTransferencia(context),
          )
        ],
      ),
    );
  }

  void _criaTransferencia(BuildContext context) {
    final int? numeroConta = int.tryParse("$_controladorCampoNumeroConta");
    final double? valor = double.tryParse("$_controladorCampoValor");
    if (numeroConta != null && valor != null) {
      final transferenciaCriada = Transferencia(valor, numeroConta);
      debugPrint("Criando Transferencia");
      Navigator.pop(context, transferenciaCriada);
    }
  }
}

class Editor extends StatelessWidget {
  final TextEditingController? controlador;
  final String? rotulo;
  final String? dica;
  final IconData? icone;

  Editor({this.controlador, this.rotulo, this.dica, this.icone});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(15.0),
      child: TextField(
        controller: controlador,
        style: TextStyle(fontSize: 24.0),
        decoration: InputDecoration(
          icon: icone != null ? Icon(icone) : null,
          labelText: rotulo,
          hintText: dica,
        ),
        keyboardType: TextInputType.number,
      ),
    );
  }
}

class Transferencia {
  final double valor;
  final int numeroConta;

  Transferencia(this.valor, this.numeroConta);

  @override
  String toString() {
    return "Transferencia{valor: $valor, numeroConta: $numeroConta}";
  }
}

class ListaTransferencias extends StatefulWidget {
  final List<Transferencia?> _transferencias = [];

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

class ListaTransferenciasState extends State<ListaTransferencias> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Transferências"),
        ),
        body: ListView.builder(
          itemCount: widget._transferencias.length,
          itemBuilder: (context, indice) {
            final transferencia = widget._transferencias[indice];
            return ItemTransferencia(transferencia!);
          },
        ),
        floatingActionButton: FloatingActionButton(
            onPressed: () {
              final Future<Transferencia?> future =
              Navigator.push(context, MaterialPageRoute(builder: (context) {
                return FormularioTrasferencia();
              }));
              future.then((transferenciaRecebida) {
                widget._transferencias.add(transferenciaRecebida);
              });
            },
            child: Icon(Icons.add)));
  }
}



class ItemTransferencia extends StatelessWidget {
  final Transferencia _transferencia;

  ItemTransferencia(this._transferencia);

  @override
  Widget build(BuildContext context) {
    return Card(
        child: ListTile(
          leading: Icon(Icons.monetization_on),
          title: Text(_transferencia.valor.toString()),
          subtitle: Text(_transferencia.numeroConta.toString()),
        ));
  }
}
2 respostas
solução!

Boa tarde Renato!

Para abordar seu problema vamos dividir ele em dois problemas menores, é o famoso dividir para conquistar!

1. A transferência não é mandada para a página de listagem

Isso está acontecendo aqui por causa da função a seguir, afinal, ela é a responsável por fechar essa tela mandando a informação para tela de listagem.

void _criaTransferencia(BuildContext context) {
    final int? numeroConta = int.tryParse("$_controladorCampoNumeroConta");
    final double? valor = double.tryParse("$_controladorCampoValor");
    if (numeroConta != null && valor != null) {
      final transferenciaCriada = Transferencia(valor, numeroConta);
      debugPrint("Criando Transferencia");
      Navigator.pop(context, transferenciaCriada);
    }
  }

O problema está especificamente no $_controladorCampoNumeroConta e no $_controladorCampoValor, pois eles estão sempre retornando null. E se retornam null, não conseguem passar pela condicional logo na sequência. Isso acontece pois o valor de texto do controlador está no parâmetro .text. E na verdade, isso já vem como string, então vamos substituir esse trecho por:

final int? numeroConta = int.tryParse(_controladorCampoNumeroConta.text);
final double? valor = double.tryParse(_controladorCampoValor.text);

Mas ainda assim, nada é mostrado na tela de listagem. Usando um debugger, conseguimos ver que o valor da transferência chegou, mas não é mostrado. Isso nos leva para a segunda parte do problema!

2. A lista de transferências não atualiza automaticamente

Esse é mais simples! Para que um widget se atualize automaticamente sabemos que ele precisa ser um "Stateful Widget", o que quer dizer que ele tem estados que variam. Sabemos que essa atualização ocorre sempre que a tela é construída, mas como fazemos para "forçar" essa reconstrução de tela?

setState((){});

É o setState que é responsável por isso, e inclusive, você só consegue usar ele dentro de um Stateful Widget. Então é isso que está acontecendo, faltou o setState. Basta que você cerque a linha que adiciona uma transferência na lista de transferências com um setState e seu código vai funcionar corretamente!

future.then(
            (transferenciaRecebida) {
              setState(() {
                widget._transferencias.add(transferenciaRecebida);
              });
            },
          );


E é isso! Espero ter ajudado, e qualquer coisa estamos aí!

Muito Obrigado Ricarth Lima, estava com mesmo erro , apliquei as soluções que você sugeriu e funcionou corretamente.