IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

Problème de dimensionnement avec la classe View


Sujet :

Composants graphiques Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut Problème de dimensionnement avec la classe View
    Bonsoir à toutes et à tous,

    Dans une application, je souhaite déposer sur un RelativeView couvrant tout l'espace de mon écran divers composants, certains descendant de Button, d'autres de View. Pas de problème avec les descendant de Button. Par contre, avec ceux descendant de View, j'ai un problème de dimensionnement : Bien qu'à la création, j'ai fixé leur dimension (setLeft, setTop, setRight et setBottom), dès qu'ils s'affichent, ils prennent la dimension de la fenêtre parent. Comment faire pour qu'ils conservent la dimension que je leur ai donnée au départ ?

    Merci de votre aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Operateur extends View {
     
        public Operateur(Context context) {
            super(context);
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            Operateur monOpe = new Operateur(this);
            monOpe.setLeft(150);
            monOpe.setTop(150);
            monOpe.setRight(250);
            monOpe.setBottom(250);
            monOpe.setBackgroundColor(0xFF8080FF);
            affSchema.addView(monOpe); // affSchema est le RelativeLayout de base couvrant tout l'écran
            valeur.setText(String.format("monOpe %d ; %d", monOpe.getWidth(), monOpe.getHeight())); // Ce TextView
    // m'indique qu'à la création, les dimensions de "monOpe" sont bien celles que je lui ai données.

    Pierre

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 4 253
    Billets dans le blog
    3
    Par défaut
    Salut !

    Le truc c'est qu'on n'est pas en programmation fonctionnelle des années 80... (même si elle est orientée objet)
    On est en événementielle...

    Le programme (la View ici en l'occurence), réagit à des événements.
    Ces événements peuvent être générés par le code lui-même, mais leur traitement sera fait à la sortie du code "utilisateur".

    Ainsi, dans le onCreate, quand on fait par exemple un "setContentView" on va mettre en place l'arborescence des views (les objets) puis faire une demande de "réorganisation" de ces views.
    Tu peux ainsi essayer sur un layout, à l'issue d'un setContentView dans le onCreate, les views auront probablement une taille de 0dp !

    Je t'invite à regarder la "vie" d'une view: http://developer.android.com/referen...view/View.html

    En l'occurence....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Operateur monOpe = new Operateur(this);
            monOpe.setLeft(150);
            monOpe.setTop(150);
            monOpe.setRight(250);
            monOpe.setBottom(250);
            monOpe.setBackgroundColor(0xFF8080FF);
    Va juste setuper un objet "Operateur" avec des données dedans, en l'occurence, une position (x,y,width,height) et une couleur de background.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            affSchema.addView(monOpe); // affSchema est le RelativeLayout de base couvrant tout l'écran
    Va dire au layout de rajouter la view dans sa liste... Il va donc se marquer comme "invalide" et faire un requestLayout() (pour repositionner ses enfants). Cette opération n'est pas synchrone, elle sera faite plus tard, quand le layout sera lui-même dimensionné (on est donc sorti du onCreate de l'activité par exemple, le layout est attaché à une fenêtre, et le système doit l'afficher).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            valeur.setText(String.format("monOpe %d ; %d", monOpe.getWidth(), monOpe.getHeight()));
    Va demander à monOpe les valeurs mises à l'étape 1... soit les trucs attendus forcément.

    ... mais un peu plus tard, un draw va arriver....
    Le draw s'apercoit que le layout n'est pas encore setupé, et va faire le requestLayout. Ce requestLayout se fait en deux étapes:
    measure() (appel de onMeasure sur les views).
    et
    layout() (appel de onLayout sur les views).

    Le premier est chargé de savoir quelle taille est nécessaire pour l'affichage de la View (la taille disponible est passée en paramètres). Ceci est important pour toutes les views en "wrap_content".
    Le second se charge positionner les views à l'intérieur du layout.
    Et c'est lui qui fera un setLeft/Top/Right/Bottom....

    Du coup à l'issue de cet appel, la view n'est plus à l'endroit indiqué lors de la création.
    D'ailleurs, la doc de setLeft & consoeurs l'indiquent clairement:


    Dans tous les cas, un RelativeLayout le fera en fonction des layout-params associés: http://developer.android.com/referen...outParams.html

    layout_width=100px
    layout_height=100px
    layout_alignParentLeft=true
    layout_alignParentTop=true
    layout_marginLeft=150px
    layout_marginTop=150px

    Reste plus qu'à espérer que ce genre de truc ne donne pas un résultat tout petit dans un coin du téléphone (sur le miens, ça fait quand même à peu prêt 4mm ! ). En tous cas, beaucoup trop petit pour un bouton par exemple...
    Ou beaucoup trop gros sur un vieux téléphone.

  3. #3
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Merci nicroman pour cette longue explication. J'avoue ne pas avoir tout bien saisi. Pour autant, je crois comprendre que tu m'expliques ce qu'il se passe et tu ne me dis pas de faire de choses supplémentaires. Dans ces conditions, tu dis obtenir un petit rectangle ; moi, j'obtiens un rectangle grand comme l'écran.

    Par ailleurs, si je remplace la classe "View" par la classe "Button" dans la définition de mon opérateur, le composant créé possède des dimensions liées au texte qu'il affiche et la position que je lui donne.

    Donc dans ce cas, mon opérateur conserve les données qu'il a eu au départ ; à la différence de celui construit avec "View".

    Il y a donc un petit plus que voudrait recréer avec la classe View. Peut être qu'avec la débogueur j'arriverai à voir quoi ?

    Pour autant, ce que je veux faire, ce sont des boutons (mes opérateurs que je peux déplacer par toucher/glisser : ça, ça marche) et des lignes de liaisons qui relient différents boutons suivant une certaines fonctionnalités. Ce seraient ces lignes qui seraient faites à partir de la classe View.

    Comme je peux déplacer les boutons, les lignes de liaisons doivent suivre. C'est à dire que leur positionnement et leurs dimensions vont varier.

    Compte tenu des difficultés potentielles à créer ces descendants de View, je me demande si cette tactique est la bonne.

    Une autre tactique serait de faire du dessin sur un canevas, les boutons et les lignes ne seraient alors que du dessin et ne descendraient d'aucune classe.

    Est-ce que cette méthode ne serait pas préférable.

    Cordialement.

    Pierre

  4. #4
    Membre émérite
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Par défaut
    Une autre tactique serait de faire du dessin sur un canevas, les boutons et les lignes ne seraient alors que du dessin et ne descendraient d'aucune classe.
    +1
    J'imagine qu'avec une seul View, qui gère et dessine les éléments, ce serait moins complexe à mettre en place et à maintenir... Et quelques part peut être plus "logique" puisque tous ses éléments semble intiment lié.
    Cela dit, je pense qu'il se sera quand même nécessaire de conserver une classe (qui n'étend de rien) pour préparer le(s) dessin du bouton et une pour celui de la(les) ligne(s).

  5. #5
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Oui LeBruz, c'est ce sur quoi je me dirige. J'ai commencé cette structure, et cela se passe sans peine (pour l'instant). Bien évidemment, il y aura une classe Operateur (et tous ses enfants : Operateur ceci, Operateur cela, ...) et une classe Liaison.

    J’essaie de transposer une application que j'avais développée en Pascal Objet pour Windows et Linux.

    J'ai de l'amusement en vue . Il va falloir que je vois comment on appelle en Java avec un seul opérateur, une classe ou un de ses enfants.

    Cordialement.

    Pierre

Discussions similaires

  1. Réponses: 3
    Dernier message: 07/07/2008, 23h03
  2. Problème de multimap avec des classes dérivées
    Par Bob94 dans le forum SL & STL
    Réponses: 3
    Dernier message: 06/05/2008, 02h02
  3. Problème d'héritage avec une classe abstraite
    Par Ph.denis dans le forum C++
    Réponses: 7
    Dernier message: 22/03/2008, 10h37
  4. Problème balise iterate avec la classe HashSet
    Par kokumbo dans le forum Struts 1
    Réponses: 8
    Dernier message: 07/11/2007, 15h43
  5. Réponses: 8
    Dernier message: 16/10/2006, 12h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo