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, System.Generics.Collections,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Platform, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Platform,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Memo, FMX.Memo.Types, 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; PMA.Vault;
const const
@@ -1155,6 +1155,9 @@ var
E: TVaultEntry; E: TVaultEntry;
LFolder: string; LFolder: string;
LBmp: TBitmap; LBmp: TBitmap;
LImg: TImage;
LBody: TLayout;
LTitle, LSub: TLabel;
begin begin
// ponytail: refonte complete de la liste a chaque frappe. Sur un coffre de // ponytail: refonte complete de la liste a chaque frappe. Sur un coffre de
// quelques centaines d'entrees c'est imperceptible ; passer a un modele // quelques centaines d'entrees c'est imperceptible ; passer a un modele
@@ -1173,13 +1176,49 @@ begin
E := FVault.Entry(FFiltered[I]); E := FVault.Entry(FFiltered[I]);
LItem := TListBoxItem.Create(FList); LItem := TListBoxItem.Create(FList);
LItem.Parent := FList; LItem.Parent := FList;
LItem.Text := E.Display; LItem.Height := 56;
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.Tag := FFiltered[I]; // indice dans le coffre, pas dans la liste 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; end;
finally finally
FList.EndUpdate; FList.EndUpdate;