I'm new to Flutter and I have to make a list of rules where every item in the list is green and if you break a rule you can press it and change the color to red. I also have to have extensible.
I also have to have extensible. In my implementation from the YouTube tutorial, I saw that I used .map()
to map the items in the list, but now when I have to press and change the color, all items change, not just one.
Any ideas how to fix this?
class _MyHomePageState extends State<MyHomePage> {
bool isSelected = true;
static const lawText =
' example text of the laws that are going to be implemented inside here. This is only to fill out the space at the moment';
final List<Item> items = [
Item(header: 'Law 1 ' , body: lawText),
Item(header: 'Law 2 ' , body: lawText),
Item(header: 'Law 3 ' , body: lawText),
Item(header: 'Law 4 ' , body: lawText),
Item(header: 'Law 5 ' , body: lawText),
];
@override
Widget build(BuildContext context) => Scaffold(
drawer: NavBar(),
appBar: AppBar(
title: Text('§ Regel'),
centerTitle: true,
),
body: SingleChildScrollView(
//crossAxisAlignment : crossAxisAlignment,
child:ExpansionPanelList(
expansionCallback: (index, isExpanded) {
setState(() => items[index].isExpanded = !isExpanded);
},
children: items
.map((item) => ExpansionPanel(
isExpanded: item.isExpanded,
headerBuilder:(context, isExpanded) => ListTile(
tileColor: isSelected ? Colors.green : Colors.red,
onTap: () => setState(() => isSelected = !isSelected),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title:Text(
item.header,
style: TextStyle(fontSize: 20),
),
),
body: ListTile(
title: Text(item.body, style: TextStyle(fontSize: 20) ),
//tileColor: Colors.lightGreen,
//onTap: () => setState(() => isSelected = !isSelected),
),
))
.toList(),
),
),
);
}
class Item {
final String header;
final String body;
bool isExpanded;
Item({
required this.header,
required this.body,
this.isExpanded = false,
});
}
I try to do everything with ListTile
instead of normal list.
I also tried using elementAt(index)
but it didn't work.
CodePudding user response:
try this:
change this
tileColor: isSelected ? Colors.green : Colors.red,
to this:
tileColor: item.isExpanded ? Colors.green : Colors.red,
you have to use bool condition from parent panel
CodePudding user response:
No matter which tile you click, the isSelected
will be changed, and every tile will recognize the change since the isSelected
condition determines which color you would like to display.
So, You have to change the type of your isSelected
from bool
to String
, which when you tap it, you can set the isSelected
to the label, in this way, flutter will know which tile you want to change.
String selected = '';
in your tile property
tileColor: selected == items[index].header ? Colors.green : Colors.red,
onTap: () => setState(() => selected = items[index].header),
However, for the best practice, either you can set a new field id
for the Item class, or you can use asMap()
to declare the indexes. Because sometimes, the headers could be same.