Publicité
+ Répondre à la discussion Actualité déjà publiée
Affichage des résultats 1 à 5 sur 5
  1. #1
    Membre Expert
    Avatar de MathiasSeguy
    Homme Profil pro Mathias Seguy
    Fondateur Android2EE - Formation Expertise Android
    Inscrit en
    avril 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Nom : Homme Mathias Seguy
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fondateur Android2EE - Formation Expertise Android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2011
    Messages : 117
    Points : 1 280
    Points
    1 280

    Par défaut [Tutoriel] Construire dynamiquement ses IHM Android.

    Bonjour,
    J'ai le plaisir de vous présenter un tutoriel pour apprendre à construire dynamiquement vos IHM Android:

    Construire Dynamiquement ses IHM Android.

    Cet extrait du site Android2ee (les livres de programmation pour Android : « Android A Complete Course, From Basics to Enterprise Edition ») vous permet de comprendre comment construire dynamiquement une IHM. Il vous explique comment déclarer dynamiquement des composants graphiques, les placer dans leur layout, charger des images à partir de leur nom ou URL, générer un flot de données de tests.
    Un tutoriel en libre téléchargement associé à cet article est téléchargeable sur le site Android2ee.com.
    N'hésitez pas à poster vos commentaires, remarques et autres pensées concernant cet article dans ce topic, il est là pour ça.
    Bonne journée

  2. #2
    Membre à l'essai
    Inscrit en
    juillet 2009
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : juillet 2009
    Messages : 18
    Points : 21
    Points
    21

    Par défaut

    Je trouve que ce tutorial est un contre-exemple composé de pas mal d'énormités :

    -La partie "Layout parameters management" de DynamicGui est hallucinante : on redéfinie les constantes WRAP_CONTENT, MATCH_PARENT et FILL_PARENT avec des constantes FILL, MATCH et WRAP (d'ailleurs MATCH = WRA), ça n'a aucune sens.

    -La méthode private Drawable getPicture(String urlPath) fonctionne certainement, mais il faut l’appeler dans un thread différent du thread UI via un AsyncTask, un Thread + Handler ou Thread + runOnUiThread.
    Là on a directement :
    webPicture.setImageDrawable(getPicture(post.getString("fromWebPicture")));

    -La classe GenerateData pourrait être totalement statique, pourquoi passer par un singleton ? les attributs non-statiques sont pourtant des constantes qui devraient être static final.

    -Il y a pas mal de redondances dans le code, notamment dans buildMessageGui et buildPostGui et cela mériterait d'être décomposer en sous-méthodes plus petites.

    -A aucun moment vous n'utilisez les fichiers layout XML ! La construction de l'interface en pure java est à réduire au maximum et vous semblez penser que les fichiers layouts XML ne permettent pas la construction d'interfaces dynamiques !

    -Le sujet même du tutorial est d'ajouter dynamiquement des linearLayout en fonction d'un objet modèle dont la taille est inconnu : vous réinventez la ListView en beaucoup moins bien ! Ce widget était pourtant parfaitement adapté au cas présent.

  3. #3
    Membre Expert
    Avatar de MathiasSeguy
    Homme Profil pro Mathias Seguy
    Fondateur Android2EE - Formation Expertise Android
    Inscrit en
    avril 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Nom : Homme Mathias Seguy
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fondateur Android2EE - Formation Expertise Android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2011
    Messages : 117
    Points : 1 280
    Points
    1 280

    Par défaut

    Bonjour,
    Quelle amabilité dans le ton de votre post, j'ai l'impression d'entendre une prof de français qui vient de rater son agreg pour la n° fois et se venge sur ces élèves.
    Nonobstant, voici les réponses à vos remarques:
    La partie "Layout parameters management" de DynamicGui est hallucinante : on redéfinie les constantes WRAP_CONTENT, MATCH_PARENT et FILL_PARENT avec des constantes FILL, MATCH et WRAP (d'ailleurs MATCH = WRA), ça n'a aucune sens.
    Effectivement, on peut comprendre que vous soyez halluciné, mais un appel du type getParams(WRAP, WRAP) me paraît tellement plus lisible et concis qu'un appel du type :getParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT). Du coup, oui, je redéfinis les variables pour un gain de lisibilité du code. C'est un tutoriel, il se doit d'être clair, c'est un parti pris que j'assume.
    La méthode private Drawable getPicture(String urlPath) fonctionne certainement, mais il faut l’appeler dans un thread différent du thread UI via un AsyncTask, un Thread + Handler ou Thread + runOnUiThread.
    Là on a directement :
    webPicture.setImageDrawable(getPicture(post.getString("fromWebPicture")));
    Tout d'abord, je suis d'accord avec vous, il faut utiliser des Handlers ou des AsynchTask de manière générale. En effet, si la thread d'IHM est bloquée dans un traitement plus de 5 secondes, l'ActivityManager détruit votre Activity. Bien sûr, la question est : Pourquoi ne pas le faire aussi avec la récupération des données? Et là votre remarque aurait été réellement pertinente. Donc, oui, bien sûr, toute méthode qui part charger des données doit le faire à partir d'une AsynchTask ou d'un Handler et notifier son IHM du chargement. Dans le cas présent l'AsynchTask est le pattern à utiliser. Pourquoi ne l'ai je pas fais? Pour la même raison que précédemment, c'est un tutoriel sur la construction dynamique d'IHM pas sur la récupération des données ni sur comment effectuer proprement des traitements sous Android. Donc je reste focalisé sur l'essentiel et j’épure au maximum le code.
    -La classe GenerateData pourrait être totalement statique, pourquoi passer par un singleton ? les attributs non-statiques sont pourtant des constantes qui devraient être static final.
    Une question que je pose régulièrement est "Quelle est la différence entre un singleton et une classe statique?" La différence vient du fait qu'une classe statique ne permet pas d'initialisation de données, pour le reste il n'y a pas de différence. Personnellement, j'aime bien les singletons et je préfère les utiliser plutôt qu'une classe statique quand j'ai le choix. Et vu que j'ai le choix je ne m'en prive pas. Ensuite, en J2EE, le singleton est devenu un bad design pattern depuis peu pour des raisons de distributions qui ne s'applique pas à Android. Donc, ayant le choix, je ne me prive pas d'utiliser le design pattern que je préfère.
    Il y a pas mal de redondances dans le code, notamment dans buildMessageGui et buildPostGui et cela mériterait d'être décomposer en sous-méthodes plus petites.
    Pour les lignes suivantes:
    TextView txvTitle = new TextView(this);
    txvTitle.setTextColor(0xFF000000);
    txvTitle.setText("titre message : " + message.getString("titre"));
    lilMessage.addView(txvTitle, getParams(FILL, WRAP));
    qui sont utilisées pour titre, message, description c'est possible, mais je ne vois pas ce que ça amène de réellement plus clair, le but étant de faire un tutoriel lisible, parfois ne pas factoriser favorise la compréhension et la lecture.
    A aucun moment vous n'utilisez les fichiers layout XML ! La construction de l'interface en pure java est à réduire au maximum et vous semblez penser que les fichiers layouts XML ne permettent pas la construction d'interfaces dynamiques !
    Le sujet même du tutorial est d'ajouter dynamiquement des linearLayout en fonction d'un objet modèle dont la taille est inconnu : vous réinventez la ListView en beaucoup moins bien ! Ce widget était pourtant parfaitement adapté au cas présent.
    J'ai eu cette discussion avec un relecteur qui fut très constructive. Alors, non, cela ne permet pas de construction dynamique dans le sens suivant : Si je ne connais pas la structure des données que je vais recevoir, je ne peux pas utiliser de fichier xml qui par définition sont statiques et donc induisent une connaissance initiale des données à reconstruire.
    Imaginez une seconde recevoir un flux du type
    <component><type>label</type><content>"toto"</content>...
    Il faut bien reconstruire dynamiquement son IHM et vous ne pouvez pas utiliser de fichiers xml statiques.
    C'est dans cette optique qu'est rédigé ce tutoriel.
    Dans ce cas, pourquoi ai-je utilisé des données dont le seul élément non connu était la taille de mes listes? Pour exposer un exemple facile à comprendre que les gens puissent facilement en assimiler les techniques pour pouvoir les réappliquer par la suite sur des cas plus complexes. Cet exemple est didactique, enfin j'espère.

    J'espère vous avoir permis de comprendre mes choix et les raisons de ceux ci.
    Cordialement,
    Mathias Séguy
    Fondateur Android2EE - Formation et Expertise Android
    Auteur Android2ee.com
    Docteur en Mathématiques Fondamentales
    Expert Technique de l'Agence Nationale de la Recherche
    Rédacteur sur Developpez.com
    Blog Android2EE sur DVP
    Android 2EE la programmation sous Android

  4. #4
    Modérateur

    Homme Profil pro Nicolas Romantzoff
    Ingénieur systèmes et réseaux
    Inscrit en
    février 2007
    Messages
    3 680
    Détails du profil
    Informations personnelles :
    Nom : Homme Nicolas Romantzoff
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : février 2007
    Messages : 3 680
    Points : 5 805
    Points
    5 805

    Par défaut

    J'ai juste un commentaire global.... et je suis aussi un peu contre la construction "manuelle" des views...
    La raison ? le support de multiple versions...
    Imaginons que l'attribut "textBlockType" n'existe pas en version 4.0 et il est introduit en version 5.0...
    Si on met dans le code un "myTextView.setTextBlockType()" ca marche, mais rends le code compatible android 5.0 uniquement !

    Pourquoi ne jamais utiliser les layoutInflater ? Ils sont là justement pour passer de données XML (facilement modifiables/réutilisables) à des View...
    layoutInflater.inflate(R.layout.myView); permet en un seul endroit de placer *tous* les attributs de style, sans avoir à systématiquement le faire par code.
    Et surtout, un attribut non reconnu est "passé" (l'exemple ci-dessus permet donc de continu d'avoir un code en 2.3.3, tout en ayant l'attribut pour android 5.0 !!)

  5. #5
    Membre Expert
    Avatar de MathiasSeguy
    Homme Profil pro Mathias Seguy
    Fondateur Android2EE - Formation Expertise Android
    Inscrit en
    avril 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Nom : Homme Mathias Seguy
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fondateur Android2EE - Formation Expertise Android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2011
    Messages : 117
    Points : 1 280
    Points
    1 280

    Par défaut

    Bonjour,
    Je suis aussi de plus en plus de cet avis (pour ce que tu dis, pour la gestion de la mémoire aussi). Je vais rajouter un chapitre, "Utiliser les layoutInflater (la bonne pratique)" avec un exemple.
    C'est dans ma todoList.
    Mathias Séguy
    Fondateur Android2EE - Formation et Expertise Android
    Auteur Android2ee.com
    Docteur en Mathématiques Fondamentales
    Expert Technique de l'Agence Nationale de la Recherche
    Rédacteur sur Developpez.com
    Blog Android2EE sur DVP
    Android 2EE la programmation sous Android

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •