IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Blog de Serge Girard (aka SergioMaster)

[FMX] Comment avoir des éléments de hauteur variable dans un TListView

Note : 2 votes pour une moyenne de 3,00.
par , 25/02/2021 à 12h23 (2958 Affichages)
La première chose est d'avoir une fonction qui permettra de calculer la hauteur nécessaire à l'objet texte que l'on veut agrandir. Le mieux est d'avoir une unité indépendante. Je vous propose celle-ci, sortie de mes recherches sur le net, puis modifiée pour prendre en compte un petit bogue tenace avec certains styles Android (évidemment les styles par défaut!)

Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
uses FMX.TextLayout, FMX.Math;
 
function GetTextHeight(const D: TListItemText; const Width: single): Integer;
    var  Layout: TTextLayout;
         Hauteur : Single;
    begin
      // Creer un TTextLayout pour obtenir les dimensions du texte
      Layout := TTextLayoutManager.DefaultTextLayout.Create;
      try
        Layout.BeginUpdate;
        try
          // Initialiser les paramètre du layout avec ceux de l'élément (stylé)
          Layout.Font.Assign(D.Font);
{$IFDEF ANDROID}
// bogue android RSP-14628,
// la taille de fonte par défaut (18) n'est pas toujours trouvée !
          if D.Font.IsSizeStored=false then  Layout.Font.Size:= 18;
{$ENDIF}
          Layout.VerticalAlign := D.TextVertAlign;
          Layout.HorizontalAlign := D.TextAlign;
          Layout.WordWrap := D.WordWrap;
          Layout.Trimming := D.Trimming;
          Layout.MaxSize := TPointF.Create(Width, TTextLayout.MaxLayoutSize.Y);
          Layout.Text := D.Text;
        finally
          Layout.EndUpdate;
        end;
        Hauteur:=Layout.Height; // obtention d'un single
        // petit gap supplémentaire, la hauteur d'un 'm'
        if D.Wordwrap then begin
          Layout.Text := 'm';
          Hauteur:=Hauteur+Layout.Height;
        end;
        Result := Round(Hauteur);
      finally
        Layout.Free;
      end;
    end;

Cette fonction je vais ensuite l'utiliser dans l'évènement OnUpdateObjects d'une TListView d'apparence dynamique.
Voici un design exemple

Nom : Capture_1.PNG
Affichages : 146
Taille : 6,3 Ko

⚠ Ne pas aligner Elément Libelle à Trailing

Toute l'astuce est de calculer la largeur disponible de l'objet avant de se lancer dans l'utilisation de la fonction d'obtention de la taille. Par défaut la largeur disponible d'un élément de liste peut se calculer de cette manière : LargeurDispo:=Largeur de la liste - l'espace reservé à gauche - l'espace reservé à droite.
ce qui ce traduira dans le code par

LargeurDispo:=TListView(Sender).Width - TListView(Sender).ItemSpaces.Left - TListView(Sender).ItemSpaces.Right
Dans mon exemple, j'ai aussi des élements qui vont réduire cette taille. Il faut donc récupérer ceux-ci pour ôter leurs largeurs.
Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
var
  Element: TListItemDrawable;
  LargeurMontant, LargeurCheck : Single;
begin
 
 Element:=AItem.View.FindDrawable('Verifie');
 LargeurCheck:=Element.Width;
 Element:=AItem.View.FindDrawable('Montant');
 LargeurMontant:=Element.Width;
 
 LargeurDispo:=ListeEcritures.Width - ListeEcritures.ItemSpaces.Left
               - ListeEcritures.ItemSpaces.Right - LargeurMontant
               - LargeurCheck;

C'est au tour de l'appel à la fonction GetTextHeight. Il cette fois-ci récupérer l'élément pour donner le paramètres.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 Element:=AItem.View.FindDrawable('Libelle');
 Hauteur:=GetTextHeight(TListItemText(Element), LargeurDispo);
Enfin, il n'y a plus qu'à utiliser la taille obtenue en ajoutant au besoin la position de départ voulue de l'objet. Ici il d'agit du haut de l'objet PositionDebut:=Element.PlaceOffset.Y;
Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
 Element.Height:= Hauteur;
 Element.Width := LargeurDispo;
 // Attention Height est un entier   
 AItem.Height := Hauteur + Ceil(PositionDebut); // hauteur totale de l'élément de liste

Code complet :
Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
procedure TFMain.ListeEcrituresUpdateObjects(const Sender: TObject;
  const AItem: TListViewItem);
var
  Element: TListItemDrawable;
  PositionDebut, LargeurMontant, LargeurCheck : Single;
  Hauteur : Integer;
  Coche : String;
begin
 
 if AItem.Purpose<>TListItemPurpose.None then  exit;
 
{ version < 10.4 pas de synchronisation avec le Datasource
  oblige à passer la donnée par un élément invisible}
 Element:=AItem.View.FindDrawable('ValeurVerif'); // < 10.4
 Coche:=TListItemText(Element).Text;              // < 10.4
 
 Element:=AItem.View.FindDrawable('Verifie');
// TListItemAccessory(Element).Visible:=SameText(Coche,'True'); // <10.4
 TListItemAccessory(Element).Visible:=DM.FDQEcrituresverifie.AsBoolean; // 10.4
 LargeurCheck:=Element.Width;
 
 Element:=AItem.View.FindDrawable('Montant');
 LargeurMontant:=Element.Width;
 LargeurDispo:=ListeEcritures.Width - ListeEcritures.ItemSpaces.Left
               - ListeEcritures.ItemSpaces.Right - LargeurMontant
               - LargeurCheck;
 
 Element:=AItem.View.FindDrawable('Libelle');
 Hauteur:=GetTextHeight(TListItemText(Element), LargeurDispo);
 
 PositionDebut:=Element.PlaceOffset.Y;
 Element.Height:= Hauteur ;
 Element.Width := LargeurDispo;
 AItem.Height := Hauteur + Ceil(PositionDebut);
end;

Nom : Capture.PNG
Affichages : 155
Taille : 22,2 Ko

Bien évidemment cette même technique pourrait s'appliquer à des images en adaptant une nouvelle fonction au type TImageObjectApperance.

Vous pouvez retrouver le code complet dans un de mes dépôts GitHub

Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog Viadeo Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog Twitter Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog Google Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog Facebook Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog Digg Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog Delicious Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog MySpace Envoyer le billet « [FMX] Comment avoir des éléments de hauteur variable dans un TListView » dans le blog Yahoo

Mis à jour 13/03/2021 à 11h29 par SergioMaster

Catégories
Delphi , FMX

Commentaires

  1. Avatar de NABIL74
    • |
    • permalink
    Merci pour ton partage! Je trouve cela très intéressant!