Mi pantalla de inicio es una Scaffold con una lista de Dismissible widgets en su cuerpo. El hijo de cada Dismissible es un widget personalizado que creé, llamado Box. Tengo un FloatingActionButton que me lleva a una nueva pantalla donde puedo agregar más Box es a la lista. (Cada Box recibe una cadena como argumento, que se usa como título).

Quiero que el método onDismissed muestre un SnackBar con el texto "(Título del cuadro) excluido". Sin embargo, esto no funciona como se esperaba. El problema es que siempre muestra el título del último cuadro incluido, y no el título del que acabo de descartar. Por ejemplo, si agrego una Box llamada "Caja 1", y luego una Box llamada "Caja 2", y luego descarto la "Caja 1", la cafetería dirá "Caja 2 excluida ".

¿Qué estoy haciendo mal?

Aquí está el código relevante:

import 'package:flutter/material.dart';
import 'box.dart';
import 'addCounter.dart';

class Home extends StatefulWidget {
  @override
  HomeState createState() => HomeState();
}

class HomeState extends State<Home> {

  List<String> lista;

  void incrementLista(String novoItem) {
    print('$lista');
    setState(() {
      lista.add(novoItem);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Counters'),
        backgroundColor: Colors.black,
      ),
      body: ListView.builder(
        itemCount: lista.length,
        itemBuilder: (context, index) {
          return Dismissible(
              background: Container(color: Colors.grey[800], child: Icon(Icons.delete, color: Colors.grey[100])),
              key: Key(lista[index]),
              onDismissed: (direction) {
                setState(() {
                  lista.removeAt(index);
                });
                Scaffold.of(context).showSnackBar(
                    SnackBar(content: Text(lista[index] + ' excluded.')));
              },
              child: Box(lista[index]));
        },
      ),
      floatingActionButton: FloatingActionButton(
          backgroundColor: Colors.grey[1000],
          onPressed: () {
            //Navega para tela de adicionar tarefa
            Navigator.push(
                context,
                MaterialPageRoute(
                    builder: (context) => AddCounter(f: incrementLista)));
          },
          child: Icon(Icons.add, color: Colors.white)),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomNavigationBar(
        //backgroundColor: Colors.grey[50],
        unselectedItemColor: Colors.grey[700],
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.list),
            title: Text('List'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.insert_chart),
            title: Text('Chart'),
          ),
        ],
        // currentIndex: _selectedIndex,
        selectedItemColor: Colors.blue,
        //onTap: _onItemTapped,
      ),
    );
  }
}

Y aquí está el código del addCounter.dart:

import 'package:flutter/material.dart';

class AddCounter extends StatefulWidget {
  final Function f;
  AddCounter({@required this.f});

  @override
  _AddCounterState createState() => _AddCounterState();
}

class _AddCounterState extends State<AddCounter> {
  final myController = TextEditingController();

  @override
  void dispose() {
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Add a counter'),
          backgroundColor: Colors.blue,
        ),
        body: Column(children: [
          Padding(
            padding: EdgeInsets.all(15),
            child: TextField(
              controller: myController,
              decoration: InputDecoration(
                  enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.blue, width: 2)),
                  hintText: 'Type a name for the counter'),
            ),
          ),
          RaisedButton(
            color: Colors.green,
            onPressed: () {
              widget.f(myController.text);
              Navigator.pop(context);
            },
            child: Text(
              'Save',
              style: TextStyle(color: Colors.white),
            ),
          )
        ]));
  }
}
0
gustgon1212 29 ago. 2020 a las 15:36

1 respuesta

La mejor respuesta

Creo que el problema es que primero eliminas el elemento de la lista. Cuando muestra el SnackBar, el elemento ya está eliminado, por lo que no puede acceder a él en la lista. Por lo tanto, sugeriría mostrar primero la barra de bocadillos y luego eliminar el elemento.

Así: (en tu itemBuilder)

return Dismissible(
          background: Container(color: Colors.grey[800], child: Icon(Icons.delete, 
                          color: Colors.grey[100])),
          key: Key(lista[index]),
          onDismissed: (direction) {
            Scaffold.of(context).showSnackBar(
                SnackBar(content: Text(lista[index] + ' excluded.')));

            setState(() {
              lista.removeAt(index);
            });
          },
          child: Box(lista[index]));
    },
1
Ruben Röhner 29 ago. 2020 a las 13:54