Reputation: 81
I have a word game app in which I give the user a letter rack to type letters from. When the user types a letter, it goes into an array and that array is reflected into an answer rack on the screen (if the user selects the correct letters and makes the right word, he gets points) The setup of this app is that the letter rack is a separate widget, the array is a global array managed by a provider and the answer rack is another widget which listens to that provider.
In case of my debug apk, when I type a letter it reflects perfectly onto the answer rack i.e. the user types a letter -> a function adds it to the array -> the answer rack widget is listening to the provider that manages the array -> answer widget rebuilds and the typed letter is reflected on the screen. However, in case of the release apk, the last step is not happening i.e. the widget does not rebuild. The letter is entered into the array which I can see by printing the array, but the widget does not rebuild. If I force the rebuild by tapping some buttons on the screen, the typed letter gets reflected on the screen.
I have tried all the solutions suggested on SOF to fix issues between debug and release apk i.e.
Adding Internet permission
...
<uses-permission android:name="android.permission.INTERNET"/>
...
</manifest>```
Flutter clean and rebuild for release
flutter build apk --release```
Removing ShrinkResources and MinifyEnabled. I've tried both options setting to true and false. Note: I am using ProGuard and I cannot compile if I remove that
release {
signingConfig signingConfigs.config
shrinkResources false
minifyEnabled false
}
}```
I have also added these lined to my ProGuardRules.pro file:
#Flutter Wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
In short, I've tried everything here: Flutter Release apk is not working properly? and other solutions given in SOF but of no avail.
Can anyone help me understand what else I could do.
Here is the code of the function in the provider which updates the array. The entire code is a lot to paste here so just adding the main snippet. Note: The array is empty at start but when a user removes a letter at any position in the array, we replace it with a space. Hence you will see code where we replace the first space with the tapped letter.
void updateLetters(String part, String letter, int index) {
int p1Space; // flag if part 1 has any spaces
int p2Space; // flag if part 2 has any spaces
p1Space = typedLetters_1.indexOf(' ');
p2Space = typedLetters_2.indexOf(' ');
wrongAnswer = false;
showCorrectMsg = false; // flag to show 'Thats Correct'
showWrongMsg = false; // Flag to show 'Try again'
if (part == 'part_1' &&
typedLetters_1.length <= _clueList[_questionIndex].answer_1.length) {
if (p1Space != -1) {
typedLetters_1.replaceRange(p1Space, p1Space + 1, [letter]);
reduceBoxSize(index, part);
} else if (typedLetters_1.length <
_clueList[_questionIndex].answer_1.length) {
typedLetters_1.add(letter);
typedIndex1.add(index);
reduceBoxSize(index, part);
}
} else if (part == 'part_2' &&
typedLetters_2.length <= _clueList[_questionIndex].answer_2.length) {
if (p2Space != -1) {
typedLetters_2.replaceRange(p2Space, p2Space + 1, [letter]);
reduceBoxSize(index, part);
} else if (typedLetters_2.length <
_clueList[_questionIndex].answer_2.length) {
typedLetters_2.add(letter);
typedIndex2.add(index);
reduceBoxSize(index, part);
}
}
checkAnswer(part);
}
void checkAnswer(String part) {
int p1Space;
int p2Space;
if (part == 'part_1' &&
typedLetters_1.length == _clueList[_questionIndex].answer_1.length) {
String userAns_1 = typedLetters_1.join('');
if (userAns_1.toUpperCase() ==
_clueList[_questionIndex].answer_1.toUpperCase()) {
part1Correct = true;
wrongAnswer = false;
showCorrectMsg = true;
} else {
wrongAnswer = true;
p1Space = typedLetters_1.indexOf(
' '); // checking again if any open spaces are still present - only if not show try again msg
if (p1Space == -1) showWrongMsg = true;
}
}
if (part == 'part_2' &&
typedLetters_2.length == _clueList[_questionIndex].answer_2.length) {
String userAns_2 = typedLetters_2.join('');
if (userAns_2.toUpperCase() ==
_clueList[_questionIndex].answer_2.toUpperCase()) {
part2Correct = true;
wrongAnswer = false;
showCorrectMsg = true;
} else {
wrongAnswer = true;
p2Space = typedLetters_2.indexOf(' ');
if (p2Space == -1) showWrongMsg = true;
}
}
if (part1Correct == true && part2Correct == true) rightAnswer = true;
notifyListeners();
}
Upvotes: 1
Views: 532
Reputation: 21
The widget tree is not rebuilding when changes occur to the provider, so in order to make widget tree rebuild use empty setState((){})
below, after changing provider variables. This will only work for StatefulWidgets.
You could also try to use setState instead of provider, to make changes by passing onChange function to other widgets.
Upvotes: 0