Search code examples
listflutterindexingcolorscontainers

Attaching Index To List Item (string) [Flutter]


Instead of making isSelected bool variable, i'll like to make it as index of selected. then check for the index of selected in reportReasons list.

This is to know which reason is being selected. Also, how do I then make the selected container change color if isSelected is not a bool?

Thank you.

final List<String> reportReasons = [
  'blah',
'blah blah',
'blah blah blah'
];

List<String> chosenReasonsToReport = [];
bool isSelected = false;

  Container(
                child: Wrap(
                    children: reportReasons
                        .map((reportReason) => GestureDetector(
                              onTap: () {
                               
                                setState(() { if (isSelected = false) {
                                  isSelected = true;
                                } else {
                                  isSelected = false;
                                }});
if (reportReason.isSelected && chosenReasonsToReport.length < 3) {
      chosenReasonsToReport.add('${reportReason}');

      print(chosenReasonsToReport);
    } else {
      chosenReasonsToReport.remove('${reportReason}');
     
      print(chosenReasonsToReport);
    }
                              },
                              child: Container(
                                margin: EdgeInsets.only(
                                  right:
                                      MediaQuery.of(context).size.width * 0.021,
                                  bottom: MediaQuery.of(context).size.height *
                                      0.009,
                                ),
                                decoration: BoxDecoration(
                                    color: isSelected
                                        ? Color(0xff4aa3f8)
                                        : Color(0xff3a327f),
                                    borderRadius: BorderRadius.circular(12),
                                    border: Border.all(
                                        color:
                                            Colors.grey[50].withOpacity(0.60))),
                                padding: EdgeInsets.symmetric(
                                    horizontal:
                                        MediaQuery.of(context).size.width *
                                            0.027,
                                    vertical:
                                        MediaQuery.of(context).size.height *
                                            0.0045),
                                child: Text(
                                  reportReason,
                                  style: TextStyle(
                                      fontSize: 13.5,
                                      color: isSelected
                                          ? Color(0xff231b6a)
                                          : null),
                                ),
                              ),
                            ))
                        .toList()),

Solution

  • You can use a couple of approaches:

    1. A set of indexes:
    class _MyScreenState extends State<MyScreen> {
      static const List<String> _reportReasons = [
        'blah',
        'blah blah',
        'blah blah blah'
      ];
    
      Set<int> _chosenIndexes = {};
      
      @override
      Widget build(BuildContext context) {
        return ListView(
          children: List.generate(_reportReasons.length, (i) {
            return Container(
              // Change property based on report selection
              color: _chosenIndexes.contains(i) 
                ? Colors.green 
                : Colors.red,
              child: CheckboxListTile(
                // Accessing report name
                title: Text(_reportReasons[i]),
                // Accessing if report is selected
                value: _chosenIndexes.contains(i),
                // Selecting and unselecting report
                onChanged: (v) {
                  setState(() {
                    if (v) {
                      _chosenIndexes.add(i);
                    } else {
                     _chosenIndexes.remove(i);
                    }
                  });
                }
              ),
            );
          }),
        );
      }
    }
    
    1. A map of String and booleans:
    class _MyScreenState extends State<MyScreen> {
      final Map<String, bool> _reports = {
        'blah': false,
        'blah blah': false,
        'blah blah blah': false,
      };
      
      @override
      Widget build(BuildContext context) {
        return ListView(
          children: _reports.keys.map((report) {
            return Container(
              // Change property based on report selection
              color: _reports[report] 
                ? Colors.green 
                : Colors.red,
              child: CheckboxListTile(
                // Accessing report name
                title: Text(report),
                // Accessing if report is selected
                value: _reports[report],
                 // Selecting and unselecting report
                onChanged: (v) {
                  setState(() => _reports[report] = v);
                }
              ),
            );
          }).toList(),
        );
      }
    }