fix(android): build the list rows by hand, styles cannot be trusted with them

The dark style took the row template with it: no username under the name, no
icon, and rows three times too tall. listboxitembottomdetail simply does not
exist in Dark.style, and Text/Detail/Bitmap render whatever the current style
decides.

Rows are now built explicitly - an image and a body layout, Left and Client,
where there is no order to guess - the same conclusion as the detail screen.
Same amount of code, no dependency on a template that may or may not be there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-08-15 15:55:00 +01:00
parent b5ccf63a85
commit 31ee1b45c6
+46 -7
View File
@@ -28,7 +28,7 @@ uses
System.Generics.Collections,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Platform,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Memo, FMX.Memo.Types,
FMX.ScrollBox, FMX.Layouts, FMX.Edit, FMX.ListBox,
FMX.ScrollBox, FMX.Layouts, FMX.Edit, FMX.ListBox, FMX.Objects,
PMA.Vault;
const
@@ -1155,6 +1155,9 @@ var
E: TVaultEntry;
LFolder: string;
LBmp: TBitmap;
LImg: TImage;
LBody: TLayout;
LTitle, LSub: TLabel;
begin
// ponytail: refonte complete de la liste a chaque frappe. Sur un coffre de
// quelques centaines d'entrees c'est imperceptible ; passer a un modele
@@ -1173,13 +1176,49 @@ begin
E := FVault.Entry(FFiltered[I]);
LItem := TListBoxItem.Create(FList);
LItem.Parent := FList;
LItem.Text := E.Display;
LItem.ItemData.Detail := E.Username;
LItem.StyleLookup := 'listboxitembottomdetail';
// Le setter copie le bitmap : le cache garde la propriete du sien.
if FIcons.TryGetValue(FFiltered[I], LBmp) then
LItem.ItemData.Bitmap := LBmp;
LItem.Height := 56;
LItem.Tag := FFiltered[I]; // indice dans le coffre, pas dans la liste
// CONTENU CONSTRUIT A LA MAIN, sans passer par Text/Detail/Bitmap ni par
// un StyleLookup. Ces gabarits n'existent pas dans tous les styles :
// avec Dark.style, 'listboxitembottomdetail' disparait et emporte
// l'identifiant, l'icone et la hauteur de ligne. Deux enfants seulement,
// alignes Left et Client - il n'y a alors pas d'ordre a deviner.
if FIcons.TryGetValue(FFiltered[I], LBmp) then
begin
LImg := TImage.Create(LItem);
LImg.Parent := LItem;
LImg.Align := TAlignLayout.Left;
LImg.Width := 40;
LImg.Margins.Rect := RectF(4, 8, 8, 8);
LImg.HitTest := False; // le clic doit atteindre la ligne
LImg.Bitmap.Assign(LBmp);
end;
LBody := TLayout.Create(LItem);
LBody.Parent := LItem;
LBody.Align := TAlignLayout.Client;
LBody.Margins.Rect := RectF(8, 4, 8, 4);
LBody.HitTest := False;
LTitle := TLabel.Create(LBody);
LTitle.Parent := LBody;
LTitle.Align := TAlignLayout.Top;
LTitle.Height := 26;
LTitle.HitTest := False;
LTitle.StyledSettings := LTitle.StyledSettings - [TStyledSetting.Size];
LTitle.TextSettings.Font.Size := 16;
LTitle.Text := E.Display;
// Align=Client sur le second : avec un Top et un Client, la place de
// chacun est determinee, quel que soit l'ordre des enfants.
LSub := TLabel.Create(LBody);
LSub.Parent := LBody;
LSub.Align := TAlignLayout.Client;
LSub.HitTest := False;
LSub.Opacity := 0.6;
LSub.StyledSettings := LSub.StyledSettings - [TStyledSetting.Size];
LSub.TextSettings.Font.Size := 12;
LSub.Text := E.Username;
end;
finally
FList.EndUpdate;