Flutter item builder not treating duplicates as different items

Issue

I am making a flutter game where I have made a virtual keyboard using item builder and the keyboard contains some characters and these characters can be duplicate, when i select any character it is showed in containers above keyboard.
The problem is when I select any particular character, its duplicates are also selected but I want to treat duplicates as different. Refer image below

enter image description here

I think this is happening due to list.contains I used in my code, check the code below


import 'package:flutter/material.dart';

class PuzzlePage extends StatefulWidget {
  int? id;
  String? image1;
  String? image2;
  String? puzzleAnswer;


  PuzzlePage(this.id, this.image1, this.image2, this.puzzleAnswer);

  State<StatefulWidget> createState()
  {
    return _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
  }


//State<StatefulWidget> createState() {
//  return _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
}

class _PuzzlePageState extends State<PuzzlePage> {
  int? id;
  String? image1;
  String? image2;
  String? puzzleAnswer;
  String? randomCharactersString="";
  List selection=[];
  _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
  void initState(){
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    // deciding keyboard size
    int? remainingLetters=26-(puzzleAnswer!.length);
    int extraSize=(remainingLetters/2).ceil();
    // print(extraSize);
    // print(puzzleAnswer!.length);
    int keyboardSize=puzzleAnswer!.length+extraSize;
    if(randomCharactersString==""){
      randomCharactersString = RandomString(extraSize, puzzleAnswer!);
    }
    String keyboardWords=randomCharactersString!+puzzleAnswer!;
    // print(randomCharactersString);
    print(selection);
// const answer= "cde";
    //final id = ModalRoute.of(context)!.settings.arguments as Id ;
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title:Text("Guess the answer"),
          centerTitle: true,
          automaticallyImplyLeading: true,
          leading: IconButton(icon:Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
        body: Container(

          color: Colors.white54,
          child: Column(
            children: [
              SizedBox(
                height: 60,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                      height: 125,
                      width: 125,
                      child: Image(image: AssetImage("assets/images/$image1"))),
                  SizedBox(
                    width: 20,
                  ),
                  Text("$randomCharactersString"),
                  Container(
                      height: 125,
                      width: 125,
                      child: Image(image: AssetImage("assets/images/$image2"))),
                ], ),
              Column(
                children: [
                  Container(
                      height: 250,
                      padding: EdgeInsets.all(10),
                      alignment: Alignment.center,
                      child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        // childAspectRatio: 1,
                        crossAxisCount: 7,
                        crossAxisSpacing: 4,
                        mainAxisSpacing: 4,
                      ),
                          itemCount: puzzleAnswer!.length,
                          shrinkWrap: true,
                          itemBuilder: (context , index){
                        print(index);
                          
                           if(selection.length>index){
                             return InkWell(
                               onTap: () {
                                 setState(() {
                                   if (!selection.contains(keyboardWords[index])){
                                     null;
                                   }

                                   else{
                                     selection.remove(keyboardWords[index]);
                                   }
                                 });
                               },
                               child: Container(
                                 padding: EdgeInsets.all(10),
                                 alignment: Alignment.center,
                                 decoration: BoxDecoration(
                                   color:Colors.blue,
                                     borderRadius: BorderRadius.circular(7)
                                 ),
                                 child: Text(selection[index],
                                     style: TextStyle(color: Colors.black)
                                 ),
                               ),
                             );
                           }
                           else{
                             return Container(
                               padding: EdgeInsets.all(10),
                               alignment: Alignment.center,
                               decoration: BoxDecoration(
                                 color: Colors.blue,
                                   borderRadius: BorderRadius.circular(7)
                               ),
                               child: Text("",
                                   style: TextStyle(color: Colors.black)
                               ),
                             );
                           }


                          }

                      )
                  ),
                ],
              ),
              Expanded(child:
              Container(
                // height: 300,
                  padding: EdgeInsets.all(10),
                  alignment: Alignment.center,
                  child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    childAspectRatio: 1,
                    crossAxisCount: 7,
                    crossAxisSpacing: 4,
                    mainAxisSpacing: 4,
                  ),
                      itemCount: keyboardSize,
                      // shrinkWrap: true,
                      itemBuilder: (context , index)
                      {
                        return InkWell(
                          onTap:(){
                            setState(() {
                              if (!selection.contains(keyboardWords[index])){
                                selection.add(keyboardWords[index]);
                              }

                                else{
                                  selection.remove(keyboardWords[index]);
                              }
                            }
                      );
                          },
                          child: Container(
                            padding:EdgeInsets.all(10),
                            alignment:Alignment.center,
                            decoration:BoxDecoration(
                              color:selection.contains(keyboardWords[index])?Colors.blueAccent:Colors.grey,
                                borderRadius:BorderRadius.circular(7)
                            ),
                            child:Text(keyboardWords[index],
                                style:TextStyle(color:Colors.black)
                            ),
                          ),
                        );

                        // return ElevatedButton(
                        //   style: ElevatedButton.styleFrom(
                        //     primary: Colors.purple,
                        //     // padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
                        //     textStyle: TextStyle(
                        //         fontSize: 20,
                        //         fontWeight: FontWeight.bold
                        //     ),
                        //   ),
                        //     onPressed: null,
                        //     child: Text("d"),
                        // );
                      }
                  )
              ),
              ),
            ],
          ),
        ),

      ),
    );
  }
}

RandomString(int strlen,String puzzleAnswer){
  Random rnd = new Random();
  String result = "";
  const chars = "abcdefghijklmnopqrstuvwxyz";
  for (var i = 0; i < strlen; i++) {
    // if (!puzzleAnswer.contains(chars[i])) {
    result += chars[rnd.nextInt(chars.length)];
    // }
  }
  return result;
}

Solution

Here is the modified file, here it does not highlight the duplicates:

import 'dart:math';

import 'package:flutter/material.dart';

class PuzzlePage extends StatefulWidget {
  int? id;
  String? image1;
  String? image2;
  String? puzzleAnswer;


  PuzzlePage(this.id, this.image1, this.image2, this.puzzleAnswer);

  State<StatefulWidget> createState()
  {
    return _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
  }


//State<StatefulWidget> createState() {
//  return _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
}

class _PuzzlePageState extends State<PuzzlePage> {
  int? id;
  String? image1;
  String? image2;
  String? puzzleAnswer;
  String? randomCharactersString="";
  List<int> selection=[];
  _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
  void initState(){
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    // deciding keyboard size
    int? remainingLetters=26-(puzzleAnswer!.length);
    int extraSize=(remainingLetters/2).ceil();
    // print(extraSize);
    // print(puzzleAnswer!.length);
    int keyboardSize=puzzleAnswer!.length+extraSize;
    if(randomCharactersString==""){
      randomCharactersString = RandomString(extraSize, puzzleAnswer!);
    }
    String keyboardWords=randomCharactersString!+puzzleAnswer!;
    // print(randomCharactersString);
    print(selection);
// const answer= "cde";
    //final id = ModalRoute.of(context)!.settings.arguments as Id ;
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title:Text("Guess the answer"),
          centerTitle: true,
          automaticallyImplyLeading: true,
          leading: IconButton(icon:Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
        body: Container(

          color: Colors.white54,
          child: Column(
            children: [
              SizedBox(
                height: 60,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                      height: 125,
                      width: 125,
                      child: Image(image: AssetImage("assets/images/$image1"))),
                  SizedBox(
                    width: 20,
                  ),
                  Text("$randomCharactersString"),
                  Container(
                      height: 125,
                      width: 125,
                      child: Image(image: AssetImage("assets/images/$image2"))),
                ], ),
              Column(
                children: [
                  Container(
                      height: 250,
                      padding: EdgeInsets.all(10),
                      alignment: Alignment.center,
                      child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        // childAspectRatio: 1,
                        crossAxisCount: 7,
                        crossAxisSpacing: 4,
                        mainAxisSpacing: 4,
                      ),
                          itemCount: puzzleAnswer!.length,
                          shrinkWrap: true,
                          itemBuilder: (context , index){
                            print(index);

                            if(selection.length>index){
                              return InkWell(
                                onTap: () {
                                  setState(() {
                                    if (!selection.contains(index)){
                                      null;
                                    }

                                    else{
                                      selection.remove(index);
                                    }
                                  });
                                },
                                child: Container(
                                  padding: EdgeInsets.all(10),
                                  alignment: Alignment.center,
                                  decoration: BoxDecoration(
                                      color:Colors.blue,
                                      borderRadius: BorderRadius.circular(7)
                                  ),
                                  child: Text("${selection[index]}",
                                      style: TextStyle(color: Colors.black)
                                  ),
                                ),
                              );
                            }
                            else{
                              return Container(
                                padding: EdgeInsets.all(10),
                                alignment: Alignment.center,
                                decoration: BoxDecoration(
                                    color: Colors.blue,
                                    borderRadius: BorderRadius.circular(7)
                                ),
                                child: Text("",
                                    style: TextStyle(color: Colors.black)
                                ),
                              );
                            }


                          }

                      )
                  ),
                ],
              ),
              Expanded(child:
              Container(
                // height: 300,
                  padding: EdgeInsets.all(10),
                  alignment: Alignment.center,
                  child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    childAspectRatio: 1,
                    crossAxisCount: 7,
                    crossAxisSpacing: 4,
                    mainAxisSpacing: 4,
                  ),
                      itemCount: keyboardSize,
                      // shrinkWrap: true,
                      itemBuilder: (context , index)
                      {
                        return InkWell(
                          onTap:(){
                            setState(() {
                              if (!selection.contains(index)){
                                selection.add(index);
                              }

                              else{
                                selection.remove(index);
                              }
                            }
                            );
                          },
                          child: Container(
                            padding:EdgeInsets.all(10),
                            alignment:Alignment.center,
                            decoration:BoxDecoration(
                                color:selection.contains(index)?Colors.blueAccent:Colors.grey,
                                borderRadius:BorderRadius.circular(7)
                            ),
                            child: Text("${keyboardWords[selection[index]]}",
                                style:TextStyle(color:Colors.black)
                            ),
                          ),
                        );

                        // return ElevatedButton(
                        //   style: ElevatedButton.styleFrom(
                        //     primary: Colors.purple,
                        //     // padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
                        //     textStyle: TextStyle(
                        //         fontSize: 20,
                        //         fontWeight: FontWeight.bold
                        //     ),
                        //   ),
                        //     onPressed: null,
                        //     child: Text("d"),
                        // );
                      }
                  )
              ),
              ),
            ],
          ),
        ),

      ),
    );
  }
}

RandomString(int strlen,String puzzleAnswer){
  Random rnd = new Random();
  String result = "";
  const chars = "abcdefghijklmnopqrstuvwxyz";
  for (var i = 0; i < strlen; i++) {
    // if (!puzzleAnswer.contains(chars[i])) {
    result += chars[rnd.nextInt(chars.length)];
    // }
  }
  return result;
}

Answered By – stacktrace2234

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published