Solved: Adding words to the list in the correct order

Question

Asked by zeed on January 10, 2022 (source).

I'm trying to adjust the words to form the sentence in the correct order. Like this. Or like Duolingo sentence examples. (without drag and drop, just lists and/or maps)

Sentence:

static String mySentence = "My cat is black";

static List<String> correctWords = mySentence.split(" ");

static List<String> shuffleWords = [...correctWords]..shuffle();

Green part: shuffleWidgetList. A widget has been added to each word in the shuffleWords.

List<Widget> shuffleWidgetList = [];
    
generateShuffleWidgets() {
  for (int i = 0; i < shuffleWords.length; i++) {
    shuffleWidgetList.add(shuffleWordWidget(shuffleWords[i]));
  }
}

Blue part: answerWidgetList.

List<Widget> answerWidgetList = [];

White part: The answer is checked with the button. I am comparing the list of words (List<String>) correctWords with answerWords.

onTap: () {
                  if (IterableEquality().equals(correctWords, answerWords)) {
                    print("correct");
                  } else {
                    print("wrong");
                  }
                },

Steps:

1. In the green part, I choose a word from the list. The item I clicked on is added to the answerWidgetList (blue part). And removed from shuffleWidgetList (green part).

onTap: () {
          setState(() {
            shuffleWidgetList.remove(shuffleWordWidget(word));
            //not necessary remove. Look at Problem 1.a
            answerWidgetList.add(answerWordWidget(word));
            answerWords.add(word);
          });
        },

2. Clicking on a word in the blue part adds it to its old place in the shuffleWidgetList(green part). And it is removed from answerWidgetList (blue part).

onTap: () {
          setState(() {
            shuffleWidgetList.add(shuffleWordWidget(word)); //Problem 1.b
            answerWidgetList.remove(answerWordWidget(word)); //Problem 2
            answerWords.remove(word);
          });
        },

Problems:

1.a. How can I change shuffleWordWidget's text color when I click an item in shuffleWidgetList?

I tried: In the shuffleWidgetList(green part) it is unnecessary to remove the item when clicking. Text should be transparent (to keep the widget size) and not be clicked again. For this I added bool clicked=false; to shuffleWordWidget. When clicked, onTap() updates to true, but color doesn't update. Like this:

shuffleWordWidget(String word) {
    bool clicked = false;
    return InkWell(
      child: Container(
        color: clicked == false ? Colors.white54 : Colors.grey,
        child: Text(
          word,
          style: TextStyle(fontSize: 12,color:clicked == false ? Colors.black : Colors.transparent ),
        ),
      ),
      onTap: () {
        if (clicked == false) {
          setState(() {
            ...
            clicked = true;
          });
        }
      },
    );
  }

1.b. How can I add shuffleWidgetList to its old place when an item is clicked in answerWidgetList?

For old place; that if the user clicks on a word from the answerWidgetList(blue part), it should be the same word clicked=false; again in the shuffleWidgetList(green part).

2. How can I remove item from answerWidgetList when I click an item in answerWidgetList?

answerWidgetList.remove(answerWordWidget(word)); doesn't work.

My approach may be completely wrong. You can also suggest different solutions.

Full code:

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Sentence Creation',
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

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

class _HomePageState extends State<HomePage> {
  static String mySentence = "My cat is black";

  static List<String> correctWords = mySentence.split(" ");

  static List<String> shuffleWords = [...correctWords]..shuffle();

  List<String> answerWords = [];

  List<Widget> shuffleWidgetList = [];
  List<Widget> answerWidgetList = [];

  generateShuffleWidgets() {
    for (int i = 0; i < shuffleWords.length; i++) {
      shuffleWidgetList.add(shuffleWordWidget(shuffleWords[i]));
    }
  }

  @override
  void initState() {
    super.initState();
    generateShuffleWidgets();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(
              flex: 2,
              child: Container(
                color: Colors.blue,
                child: Center(
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: answerWidgetList,
                  ),
                ),
              )),
          Expanded(
            child: Container(
              color: Colors.green,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: shuffleWidgetList,
              ),
            ),
          ),
          SizedBox(
            height: 50,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: InkWell(
                child: Center(child: Text("Check")),
                onTap: () {
                  if (IterableEquality().equals(correctWords, answerWords)) {
                    print("correct");
                  } else {
                    print("wrong");
                  }
                  print("correct list: $correctWords");
                  print("answer list: $answerWords");
                },
              ),
            ),
          )
        ],
      ),
    );
  }

  shuffleWordWidget(String word) {
    return Padding(
      padding: const EdgeInsets.all(4.0),
      child: InkWell(
        child: Container(
          color: Colors.white54,
          child: Padding(
            padding: const EdgeInsets.all(4.0),
            child: Text(
              word,
              style: TextStyle(fontSize: 12),
            ),
          ),
        ),
        onTap: () {
          setState(() {
            shuffleWidgetList.remove(shuffleWordWidget(word));
            //not necessary remove. Look at Problem 1.a
            answerWidgetList.add(answerWordWidget(word));
            answerWords.add(word);
          });
        },
      ),
    );
  }

  answerWordWidget(String word) {
    return Padding(
      padding: const EdgeInsets.all(4.0),
      child: InkWell(
        child: Container(
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(4.0),
            child: Text(
              word,
              style: TextStyle(fontSize: 12),
            ),
          ),
        ),
        onTap: () {
          setState(() {
            shuffleWidgetList.add(shuffleWordWidget(word)); //Problem 1.b
            answerWidgetList.remove(answerWordWidget(word)); //Problem 2
            answerWords.remove(word);
          });
        },
      ),
    );
  }
}

Answer

Question answered by Pranav (source).

Put this code in _HomePageState.

static String mySentence = "My cat is black";

  static List<String> correctWords = mySentence.split(" ");

  static List<String> shuffleWords = [...correctWords]..shuffle();


  List<String> answerWords = [];

  List<Widget> shuffleWidgetList = [];
  List<Widget> answerWidgetList = [];

  generateShuffleWidgets() {
    for (int i = 0; i < shuffleWords.length; i++) {
      shuffleWidgetList.add(shuffleWordWidget(shuffleWords[i],true));
    }
  }

  @override
  void initState() {
    super.initState();
    generateShuffleWidgets();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(
              flex: 2,
              child: Container(
                color: Colors.blue,
                child: Center(
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: answerWidgetList,
                  ),
                ),
              )),
          Expanded(
            child: Container(
              color: Colors.green,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: shuffleWidgetList,
              ),
            ),
          ),
          SizedBox(
            height: 50,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: InkWell(
                child: Center(child: Text("Check")),
                onTap: () {
                  if (IterableEquality().equals(correctWords, answerWords)) {
                    print("correct");
                  } else {
                    print("wrong");
                  }
                  print("correct list: $correctWords");
                  print("answer list: $answerWords");
                },
              ),
            ),
          )
        ],
      ),
    );
  }

  shuffleWordWidget(String word,bool visible) {
    return Visibility(
      visible: visible,
      child: Padding(
        padding: const EdgeInsets.all(4.0),
        child: InkWell(
          child: Container(
            color: Colors.white54,
            child: Padding(
              padding: const EdgeInsets.all(4.0),
              child: Text(
                word,
                style: TextStyle(fontSize: 12),
              ),
            ),
          ),
          onTap: () {
            setState(() {
              //shuffleWidgetList.remove(shuffleWordWidget(word));
              int i = shuffleWords.indexOf(word);
              shuffleWidgetList[i]=shuffleWordWidget(word,false);
              //not necessary remove. Look at Problem 1.a
              answerWidgetList.add(answerWordWidget(word));
              answerWords.add(word);
            });
          },
        ),
      ),
    );
  }

  answerWordWidget(String word) {
    return Padding(
      padding: const EdgeInsets.all(4.0),
      child: InkWell(
        child: Container(
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(4.0),
            child: Text(
              word,
              style: TextStyle(fontSize: 12),
            ),
          ),
        ),
        onTap: () {
          setState(() {
            int i = shuffleWords.indexOf(word);
           // shuffleWidgetList.insert(i,shuffleWordWidget(word)); //Problem 1.b
            shuffleWidgetList[i]=shuffleWordWidget(word,true);
            int y = answerWords.indexOf(word);
            answerWidgetList.removeAt(y); //Problem 2
            answerWords.remove(word);
          });
        },
      ),
    );
  }

I added a visibility detector which is triggered with a bool value. I used the shuffleWords list to get the index of the widget and hid it by changing the bool to false. Similarly answerWords can be used for removing widgets from answerWidgetList. As the widget from answerWidgetList is removed therefore we don't need visibility widget there.

Or if shuffleWordWidget is replaced with this then Visibility() is not needed and the image in the question is obtained.

  shuffleWordWidget(String word, bool visible) {
    return Padding(
      padding: const EdgeInsets.all(4.0),
      child: InkWell(
        child: Container(
          color: visible == true ? Colors.white54 : Colors.grey,
          child: Padding(
            padding: const EdgeInsets.all(4.0),
            child: Text(
              word,
              style: TextStyle(
                  fontSize: 12,
                  color: visible == true ? Colors.black : Colors.transparent),
            ),
          ),
        ),
        onTap: () {
          if (visible == true) {
            setState(() {
              //shuffleWidgetList.remove(shuffleWordWidget(word));
              int i = shuffleWords.indexOf(word);
              shuffleWidgetList[i] = shuffleWordWidget(word, false);
              //not necessary remove. Look at Problem 1.a
              answerWidgetList.add(answerWordWidget(word));
              answerWords.add(word);
            });
          }
        },
      ),
    );
  }
DART FLUTTER LIST
SHARE: