skip to Main Content

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,
  });
}

ImageImage

I try to do everything with ListTile instead of normal list.
I also tried using elementAt(index) but it didn’t work.

2

Answers


  1. 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

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search