My Home Screen is a Scaffold
with a list of Dismissible
widgets at its body. The child of each Dismissible
is a custom widget I created, named Box
. I have a FloatingActionButton
that takes me to a new screen where I can add more Box
es to the list. (Each Box
receive a String as an argument, that is used as its title).
I want the method onDismissed
to show a SnackBar
with the text "(Title of the box) excluded". However, this is not working as expected. The problem is that it always displays the title of the last box included, and not the title of the one I just dismissed. For example, if I add a Box
named "Box 1", and then a Box
named "Box 2", and then I dismiss the "Box 1", the snackbar will say "Box 2 excluded".
What am I doing wrong?
Here is the relevant code:
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,
),
);
}
}
And here is the code of the 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),
),
)
]));
}
}
I think the problem is that you first remove the item of the list. When you show the SnackBar the item is already removed so you can't access it in the list. So I would suggest to first show the Snackbar and then remove the item.
Like this: (In your 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]));
},