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!)
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
⚠ 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.
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.
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;
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 :
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; |
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