Le 09 février 2021 à 11:29:32 boucif a écrit :
Perso je déteste avoir la vue dans la code, j'aime un "langage déclaratif" style Xaml, html, une habitude de "vieux" peut être, mais j'aime que chaque chose soit segmenté.
Ouais c'est assez compliqué quand tu fais la transition, après j'ai a peine un mois de Flutter derrière moi mais je me perd des fois
En soit c'est techniquement possible de séparer la partie binding de la partie statique de l'UI. Genre faut juste avoir d'un côté un widget flutter classique (partie binding) et de l'autre une fonction pour construire l'arborescence de widgets (partie statique), cette autre fonction prendrai uniquement en paramètre les variables correspondants au contenu dynamique qu'il affiche et des callback, le tout sans BuildContext.
Après j'ai jamais essayé, je sais pas quelles limitations ça pourrait avoir.
Je t'avoue que j'ai réfléchis à tenter de faire ça et proposer un plugin, mais je me demande quand j'aurai le temps pour un tel projet ...
Google a fait une vidéo pour annoncer Flutter 2 (pas de vrai changements cassants autres que la null-safety). Et ils ont parlé un peu de ceux qui bossent sur / avec Flutter.
Ils ont dit que Microsoft et Canonical contribuaient pas mal au framework, Canonical a annoncé que tous leurs nouveaux logiciels utiliseront Flutter (à commencé par leur nouveau installeur pour Ubuntu).
Toyota aussi utilise Flutter maintenant pour développer les interfaces de ses voitures.
Il y a quand même de moins en moins de raisons de douter de l'avenir de Flutter.
Un peu comme le studio google stadia.
N'empêche sacré contribution de microsoft https://pub.dev/publishers/microsoft.com/packages
[09:43:02] <boucif>
Un peu comme le studio google stadia.
En quoi ?
N'empêche sacré contribution de microsoft https://pub.dev/publishers/microsoft.com/packages
Je parle de merge request sur le repo de Flutter, pas de packages externes...
Ton but c'est d'avoir une vraie discussion sur le sujet ou juste de trouver des points sur lesquels tu peux cracher dessus ?
Le 04 mars 2021 à 09:43:02 boucif a écrit :
N'empêche sacré contribution de microsoft https://pub.dev/publishers/microsoft.com/packages
Jolie tentative de troll, sauf que si tu avais lu correctement Microsoft contribue au framework directement (les sources sont d'ailleurs open source si jamais ça t'intéresse : https://github.com/flutter/flutter )
On y trouve de nombreuses PR et feedback d'employés de Microsoft, employés qui ont un nombre d'heure par semaine à consacrer à des projets open-sources sur leur temps de travail.
Je sais que c'est "in" de vouloir cracher sur Microsoft, mais il n’empêche qu'ils contribuent énormément au monde de l'open source en s'impliquant dans des projets tiers (ou même projets internes : VS Code par ex.)
D'ailleurs c'est marrant mais si tu vas à des confs de dev, il y a énormément de conférenciers qui bossent chez Microsoft. Par exemple j'ai rencontré le créateur de Webpack, un outil très connu pour la packaging d'app JS, et le mec est chez MS et fait webpack sur son temps de travail (avec la contribution d'autres personnes évidement, c'est un projet open source).
On est jamais vraiment très sur avec Google, tant mieux que ça soit opensource il y a toujours moyen de faire un fork en cas d'abandon, après peut être que Google va se désister peu à peu au profit de la communauté.
Je sais que Microsoft participe à plein de projet opensource, je boss principalement sur leur techno, leur Framework .net core et les technos autour sont principalement opensource.
Microsoft fait de la tune sur Azure et les abonnement style Office, donc ils ouvrent leur techno en espérant que derrière tu utilise leur service, c'est un business modèle très rentable.
Et ils ont Microsoft Garage qui permet de lancer plein de projet ambitieux.
Après personnellement je n'ai pas adhérer à Flutter pas fan de la conception d'interface et dart me semble une régression par rapport à d'autre langage, j'espère juste qu'il offrira plus de possibilité à l'avenir, de ce côté là mais ça semble pas pour la v2 ...
Dart va continuer d'être amélioré évidemment, ils sont entrain de bosser sur la meta-programmation, avec comme objectif principal de recréer les data class de Kotlin mais via du code plutôt que via une feature du langage. Ça permettrait d'avoir quelque chose de plus flexible (ta data class est générée via du code, donc si tu veux qu'elle soit générée différemment tu peux, dans Kotlin comme c'est une feature du langage tu peux pas changer son fonctionnement).
Évidemment ça ne permettrait pas de faire que ça, mais les data class c'est une requête qu'ils ont souvent donc ils utilisent ça comme exemple.
Il y a déjà des outils de génération de code en dart, qui doivent être exécutés durant le process de build du coup, mais là l'idée c'est que ce soit intégré au langage directement, et exécuté par le compilateur en lui-même. Je sais pas vraiment quel avantage ça a par rapport au système d'annotations + étape de génération de code par contre.
Pour ce qui est de Flutter en lui-même, la manière dont les interfaces sont conçues c'est justement son point fort, ça peut être un peu simplifié (comme dans JetPack Compose qui utilise des lambdas plutôt que des listes de widgets pour définir le contenu d'un conteneur, ça rend les widgets imbriqués plus lisibles), mais le concept d'UI déclarative sera pas changé, parce que bah c'est plus Flutter sinon en fait.
Et t'as déjà plein de manières de gérer l'état de tes widgets (peut-être même trop d'ailleurs), je sais pas laquelle t'as utilisé mais tu peux en essayer d'autres (provider, bloc, redux, ...). Et tout ça t'empêche pas de séparer en différents fichiers / fonctions tes vues et ta logique. C'est juste une question d'organisation.
J'avais suivi le tuto officiel, j'ai aussi regardé du côté du pattern Mvvm mais c'est plus du bricolage j'ai l'impression.
Perso je préfère ce qu'on retrouve dans le Web: un fichier Html, un Js, un css, plutôt que de l'Html dans le JS comme on retrouve dans React, après c'est plus lié aux appréciations de chaque dev.
Mais laissé la possibilité pour le dev c'est ce qu'il y a de mieux, c'est le choix fait sur net maui https://devblogs.microsoft.com/dotnet/introducing-net-multi-platform-app-ui/
Ca me fait un peu chier de pas avoir réussi à me mettre sérieusement sur flutter à cause de ça, je me serais bien lancé dans le dev mobile de manière pro, le web c'est chiant à force ...
C'est pas forcément facile de prédire quelles technologies vont progresser et celles qui vont décliner.
Flutter 2 viens d'être annoncé et ça a l'air de faire pas mal de buzz, du moins aux USA pour l'instant : https://programmation.developpez.com/actu/313094/La-version-2-du-SDK-Flutter-de-Google-est-disponible-avec-la-prise-en-charge-des-applications-de-bureau-et-Web-ainsi-que-le-support-pour-les-appareils-pliables-et-embarques/
Sur la France il y a encore des éditeurs de logiciels qui font du développement spécifique pour une plateforme, par exemple qui cherchent des développeurs Swift pour IOS ou Java/ Kotlin pour Android.
Le 04 mars 2021 à 15:01:11 tbol a écrit :
C'est pas forcément facile de prédire quelles technologies vont progresser et celles qui vont décliner.
Flutter 2 viens d'être annoncé et ça a l'air de faire pas mal de buzz, du moins aux USA pour l'instant : https://programmation.developpez.com/actu/313094/La-version-2-du-SDK-Flutter-de-Google-est-disponible-avec-la-prise-en-charge-des-applications-de-bureau-et-Web-ainsi-que-le-support-pour-les-appareils-pliables-et-embarques/
Sur la France il y a encore des éditeurs de logiciels qui font du développement spécifique pour une plateforme, par exemple qui cherchent des développeurs Swift pour IOS ou Java/ Kotlin pour Android.
Les frameworks comme Flutter et autre n'empêcheront pas la continuité des frameworks natifs, suivant tes besoins tu pourra te contenter d'un framework multiplateform dans certains cas vaut mieux du natif, après c'est une question de budget, c'est souvent plus chère 2 applis native plutôt qu'une multi.
Dans 80% des cas un framework multiplateforme peut suffire, souvent les apps consiste à appeler des rest api et afficher/modifier les données.
De mon côté, ça fait 6 mois que je fais du flutter à temps plein pour une refonte complète d'une application Android que nous maintenons à côté (quasi pas d'évolution) + utiliser Flutter pour adresser le marché iOS.
J'ai senti le dart comme une régression par rapport à Koltin (ces foutus points-virgules...) et j'ai eu des problèmes avec diverses notions du dart et de Flutter (UI déclarative, mixin, single-threaded., les méthodes dans les méthodes, l'organisation de code permettant plus d'une classe par fichier, pattern BLoC...).
Mes pensées actuelles sont que Flutter (+ Dart) sont un peu comme l'environnement web (HTML + JS + CSS) dans le sens où il y a plein de manières de faire, et que c'est vraiment facile de faire un GROS bordel illisible et non-maintenable.
Je considérais le développement mobile comme une mauvaise approche pour des débutants développeurs en solo. Flutter me renforce dans mon avis (car je trouve qu'il est encore plus facile avec Flutter de faire un truc qui fonctionne, mais qui est une horreur en terme d'écriture et de maintenance).
Je déteste aussi totalement le mécanisme de visibilité de dart, qui est, pour moi, une erreur de conception monumentale.
Enfin, le pattern BLoC est "juste" une énième (dernière en date ?) implémentation du pattern MVC.
Ce qui m'a clairement aidé à passer le cap de l'UI déclarative, ça a été de comprendre comment le formatter Dart fonctionne, et l'utilité des "virgules inutiles". Pour illustrer :
Text('Hello, $_name! How are you?', textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold),)
aura comme rendu :
Text(
'Hello, $_name! How are you?',
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
)
à cause de la virgule après le dernier paramètre (qui est donc normalement inutile).
Ca paraît tout con, mais sur une UI un peu complexe de 100 lignes, cette aération m'a permis de commencer à lire et comprendre ce qu'il se passait (je n'en suis pas au même point que ma lecture & compréhension de XML Android néanmoins).
Il y a quand même des plugins pour faire l'interface en xml au finale :
https://pub.dev/packages/xml_layout
https://marketplace.visualstudio.com/items?itemName=WaseemDev.flutter-xml-layout
https://pub.dev/packages/xdml
[17:40:35] <boucif>
Il y a quand même des plugins pour faire l'interface en xml au finale :
https://pub.dev/packages/xml_layout
https://marketplace.visualstudio.com/items?itemName=WaseemDev.flutter-xml-layout
https://pub.dev/packages/xdml
Mais quel intérêt ? Juste parce que le XML c'est plus joli que le dart ?
Je pense pas que ce soit une bonne idée, gagner un poil de lisibilité pour perdre en fonctionnalités, performance et intégration (au lieu d'avoir une erreur à la compilation / dans l'IDE t'as une erreur au runtime) c'est pas rentable.
Je comprends que c'est agréable de rester dans un environnement familier mais aller à contre courant d'un framework c'est juste se mettre des bâtons dans les roues, si t'essaies jamais de t'adapter alors tu t'adapteras jamais.
Bunyan, un truc qui pourrait être amélioré c'est tous ces niveaux d'indentation. Genre si tu veux ajouter du padding à un objet tu dois l'encapsuler dans un widget et donc l'indenter d'un niveau de plus. Le contenu d'un container est passé dans un paramètre, donc t'as le paramètre en lui-même qui est indenté plus la valeur de ce paramètre (si c'est sur plusieurs lignes).
Avec JetPack Compose le système de padding se fait via des "modifiers" qui sont passés en paramètre, pas via des widgets qui encapsules. Le contenu est décrit via une lambda en fin de fonction (donc seulement un niveau d'indentation de plus que le conteneur), pas via une liste passé à un paramètre (deux niveaux).
Tout ça rend tes vues plus plates, donc tu peux utiliser 4 espaces pour indenter sans problème, donc au final c'est plus aéré et plus lisible.
Je sais pas si flutter pourra avoir ce genre de trucs un jour, mais ça serait cool.
Honnêtement (de ce que je comprends) de ton explication : je pense que ce serait envisageable.
J'vais p'têt y jeter un oeil plus sérieux la semaine prochaine.
En gros un truc comme ça en Flutter:
Padding(
padding: EdgeInsets.all(2),
child: Column(
children: [
Text("Stuff"),
Text("Other Stuff"),
],
),
);
Ça donne ça avec JetPack Compose:
Column(modifier = Modifier.padding(all = 2.dp)) {
Text("Stuff")
Text("Other Stuff")
}
C’est pour ça que j’ai mis de côté flutter, je me suis dit si j’ai aucun plaisir à bosser dessus que c’est plus une tare pour moi pourquoi continuer.
(précision: je vais parler de package que j'ai pas testé, j'ai seulement lu la doc, et pour ceux que j'ai testé c'était que sur des toutes petites apps donc aucune idée de si ça se scale bien ou pas)
J'ai cherché un peu ces derniers jours s'il y avait pas des packages qui facilitaient la vie pour l'écriture des apps Flutter, j'en ai trouvé quelques uns sympa donc je vais les partager.
Le premier pourrait intéresser boucif je pense, c'est flutter_mobx, c'est un package de state management qui ressemble beaucoup au combo ViewModel / LiveData d'Android je trouve, en gros ça ressemble à ça :
Partie Store :
class TopicStore = _TopicStore with _$TopicStore;
abstract class TopicStore with Store {
@observable
String name;
@observable
List<Message> messages;
@computed
int get messageCount => messages.length;
@action
Future loadTopic(String url) async {
name = "Loading..."
TopicData topicData = await /* get topic data */;
name = topicData.name;
messages = topicData.messages;
}
}
Les @observable c'est des LiveData en gros, @computed c'est des MediatorLiveData (une LiveData qui se màj en fonction d'autres LiveData) et la fonction annotée avec @action c'est celle qui permet de modifier ces observables.
Pour la partie Widget maintenant faut injecter le store, on va partir du principe que j'ai utilisé Provider parce que c'est la solution la plus standard en soit, et je vais juste montrer le widget qui gère l'affichage.
Partie Widget :
class TopicWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<TopicStore>(
builder: (_, topicStore, __) => Column(
children: [
Observer(builder: Text("Topic: ${topicStore.name} (${topicStore.messageCount})")),
Observer(builder: MessageListWidget(topicStore.messages)),
MaterialButton(onPressed: () => topicStore.loadTopic()),
],
),
);
}
}
Les Observer traquent les observables qui sont utilisés à l'intérieur du builder, et rebuild uniquement quand ces observables changent. Je trouve ça plutôt concis perso.
Un autre package pour rendre le code plus concis c'est flutter_hooks. Il y a beaucoup de boilerplate pour écrire les StatefulWidget c'est chiant, flutter_hooks les rend aussi simple à écrire que des StatelessWidget.
Un exemple où on veut cache un Widget complexe, histoire de pas avoir de problème de performance parce qu'on le rebuild tout le temps pour rien :
class SmallWidget extends HookWidget {
@override
Widget build(BuildContext context) {
final bigWidget = useMemoized(() => BigWidget());
return Card(child: bigWidget);
}
}
Voyons un peu des fonctionnalités manquantes de Dart par rapport à Kotlin, un truc qui dérange rapidement c'est les sealed class, pour ça il y a freezed. Freezed fait aussi d'autres trucs mais c'est la seule fonctionnalité que j'ai testé.
Un exemple de LoadableValue:
@freezed
class LoadableValue<T> with _$LoadableValue<T> {
const factory LoadableValue.loading() = LoadingValue;
const factory LoadableValue.loaded(T value) = LoadedValue;
const factory LoadableValue.error(String errorMessage) = ErrorValue;
}
Puis après on peut l'utiliser avec when() :
class ShowLoadableValueWidget<T> extends StatelessWidget {
final LoadableValue<T> loadableValue;
ShowLoadableValueWidget(this.loadableValue);
@override
Widget build(BuildContext context) {
return loadableValue.when(
loading: () => Text("Loading..."),
loaded: (value) => Text("Loaded: $value"),
error: (errorMessage) => Text("Error: $errorMessage"),
);
}
}
Un dernier petit point, pour réduire un peu le boilerplate pour l'écriture des StatelessWidget il y a le package functional_widget, mais il est pas encore dispo avec la sound null safety de Dart donc pas vraiment utilisable, mais il sera très certainement mis à jour (il y a une PR en cours de ce que j'ai vu), ça permettrait d'écrire le widget plus haut comme ça à la place :
@swidget
Widget showLoadableValueWidget<T>(BuildContext context, LoadableValue<T> loadableValue) {
return loadableValue.when(
loading: () => Text("Loading..."),
loaded: (value) => Text("Loaded: $value"),
error: (errorMessage) => Text("Error: $errorMessage"),
);
}
C'est un peu plus simple, et surtout ça ajoute automatiquement le paramètre "key" à vos constructeurs (chose que j'ai pas faite dans mes exemples, mais qu'il faudrait toujours faire), donc ça permet d'avoir moins de chance de mal écrire son widget.
Des petites mentions pour terminer:
built_collection: Des collections immutables. Parce que c'est bien beau d'avoir un setter privé / getter public mais si n'importe qui peut juste faire un .add() sur la liste ça sert à rien.
riverpod: Un nouveau package d'injection de dépendance / state management, par le créateur de provider (et qui a pour objectif d'être provider mais en mieux). Ça a l'air plus sympa mais si c'est pour de la pure injection de dépendance je sais pas si ça a un réel intérêt par rapport à provider.
dio: http mais en mieux (ça fait plus de trucs).