I'm currently working on a guitar app. This app has several exercices type (find and play the correct displayed note, read music notations...). Each exercice type must return 2 widgets with their states :
-
a page to play the exercice
-
a page to customize the exercice (settings page) Each exercice type has each own unique page. For example, exercice A may need 2 TextField and exercice B may need 1 dropdown button. So far, I implemented it successfully with this pattern :
I wrote an Exercice class (to store all exercices created by the user in a database) :
class Exercice {
String name;
int exerciceType;
String exerciceSettings; // <-- stored in json
}
And I created this abstract class :
abstract class ExerciceType {
int get id; // each exercice type has a unique type String get displayedName; Icon get icon;
Widget settingWidgets(); // return the settings page String toJson(); // serialize settings from the settings page in a json string Widget playPage(); // return the page where we can play the exercice
}
And then, each exercices type can be implemented like this :
class FindNote extends ExerciceType {
String displayedName = "find_note";
int id = 0;
Icon icon = Icon(Icons.audiotrack);
// this is what concerned me the most, I have to pass the state here... :(
FindNoteSettingsPage widgetSettings = FindNoteSettingsPage(state: _FindNoteSettingsPageState());
FindNotePlayPage playPages = FindNotePlayPage(state: _FindNotePlayPageState());
StatefulWidget settingWidgets() { return widgetSettings; }
StatefulWidget playPage() { return playPages; }
String toJson() {
var settings = {};
// :( bad things here I suppose...
settings["minFret"] = widgetSettings.state._values.start.toInt();
settings["maxFret"] = widgetSettings.state._values.end.toInt();
settings["strings"] =
widgetSettings.state.stringsList.stringActive;
return json.encode(settings);
}
}
class FindNoteSettingsPage extends StatefulWidget {
final _FindNoteSettingsPageState state;
FindNoteSettingsPage({Key key, @required this.state}) : super(key: key);
@override
_FindNoteSettingsPageState createState() {
return state;
}
}
class _FindNoteSettingsPageState extends State<FindNoteSettingsPage> {
// some attributes here
@override
Widget build(BuildContext context) {
return new Column(//my settings page here with TextField and so on.)
}
}
// same pattern is used to implement the play page class
So far the code is working but I'm not satisfied with this design.
For example, if I want to show to the user his exercices list, each exercice must be instantiated completly (so loading each settings/play page, custom behavior...)
I will greatly appreciate any advices that can improve this design pattern. I suppose I'm not the first to write this kind of logic in Flutter :) Thanks in advance ! I can post a link to the Github repo for anyone requesting it.
Aucun commentaire:
Enregistrer un commentaire