Search code examples
listflutterbooleancontainersconditional-operator

Change Colors of Selected Containers and Unselect? [Flutter]


They are containers filled with reasons to report a user. How to change the code so that each individual container will change color upon tab on/off? And also limit the selected reasons to 3 while printing the reasons to the chosenReportReasons list?

Attached is the truncated code:


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: () {
                                if (isSelected = false) {
                                  isSelected = true;
                                } else {
                                  isSelected = false;
                                }
                                setState(() {});
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()),

Updated error of code

Updated error of code

Further Updated:

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ReportPage(),
    );
  }
}


class RemarksModel {
  bool isSelected;
  String reason;

  RemarksModel({this.isSelected, this.reason});
}

class ReportPage extends StatefulWidget {

  List<RemarksModel> reportReasons;

  @override
  void initState() {
    super.initState();
    reportReasons = [
      RemarksModel(isSelected: false, reason: 'Sexually Harassing'),
      RemarksModel(isSelected: false, reason: 'Racially Discriminative'),
      RemarksModel(isSelected: false, reason: 'Shouting'),
      RemarksModel(isSelected: false, reason: 'Prank Calling'),
      RemarksModel(isSelected: false, reason: 'Scam Bots'),
      RemarksModel(isSelected: false, reason: 'Vulgarities Abusing'),
      RemarksModel(isSelected: false, reason: 'No Sound')
    ];
  }

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

class _ReportPageState extends State<ReportPage> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
...


Solution

  • For the ease create a Model class for Reasons

    class RemarksModel {
      bool isSelected;
      String reason;
    
      RemarksModel({this.isSelected, this.reason});
    }
    

    and can be initialized as

      List<RemarksModel> reportReasons;
    
      @override
      void initState() {
        super.initState();
        reportReasons = [
          RemarksModel(isSelected: false, reason: 'blah'),
          RemarksModel(isSelected: false, reason: 'blah blah'),
          RemarksModel(isSelected: false, reason: 'blah blah blah')
        ];
      }
    

    then you can easily know whether the item is selected or not, and you can make an item select and deselect on the tap callback

                    onTap: () {
                      setState(() {
                        reportReason.isSelected = !reportReason.isSelected;
                      });
                    },
    

    Full code

      @override
      Widget build(BuildContext context) {
        return Container(
          child: Wrap(
              children: reportReasons
                  .map((reportReason) => GestureDetector(
                        onTap: () {
                          setState(() {
                            reportReason.isSelected = !reportReason.isSelected;
                          });
                        },
                        child: Container(
                          margin: EdgeInsets.only(
                            right: MediaQuery.of(context).size.width * 0.021,
                            bottom: MediaQuery.of(context).size.height * 0.009,
                          ),
                          decoration: BoxDecoration(
                              color: reportReason.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.reason,
                            style: TextStyle(
                                fontSize: 13.5,
                                color: reportReason.isSelected
                                    ? Color(0xff231b6a)
                                    : null),
                          ),
                        ),
                      ))
                  .toList()),
        );
      }
    

    if you need a list of selected reasons only,

      List<RemarksModel> getSelectedReasons() {
        return reportReasons.where((reason) => reason.isSelected).toList();
      }