![]() |
FMX - ListView - ItemAppearance - Runtime
Hallo Community,
nach langer Zeit, stehe ich mal wieder vor einem Problem, das ich einfach nicht gelöst bekomme. Ich bin dabei, eine App für Android zu entwickeln. Dort liegt auf der Mainform ein TListView, dessen ItemAppearance auf "DynamicAppearance" steht. Ich habe einige TListItemText unter "Item" reingepackt und ausgerichtet. Da diese Elemente nicht nach dem "normalen" Prinzip von TAlignLayout.Client etc. arbeiten (bitte berichtigt mich, wenn ich falsch liege), möchte ich die Ausrichtung und Maße dieser Elemente beim ändern der Orientation anpassen. Dieses habe ich über das ResiceEvent des ListViews als auch über
Delphi-Quellcode:
ausprobiert.
TMessageManager.DefaultManager.SubscribeToMessage(TOrientationChangedMessage, OnOrientationChanged);
Drehe ich also das Gerät in die Landscape-Ansicht, sollen die TListItemText breiter werden. Leider passiert dort nichts. Führe ich die Änderungs-Procedure allerdings manuell via ButtonClick aus, werden die Änderungen übernommen. Ich weiß leider überhaupt nicht, woran das liegen kann. Hier mal die angesprochene Procedure:
Delphi-Quellcode:
Hat jemand von euch eine Idee dazu?
var
LLIT: TListItemText; LLVI: TListViewItem; LSS : IFMXScreenService; begin if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(LSS)) then begin if LSS.GetScreenOrientation in [TScreenOrientation.soPortrait, TScreenOrientation.soInvertedPortrait] then begin Toast('Portrait'); for LLVI in lvInventar.Items do begin LLIT := TListItemText(LLVI.Objects.FindDrawable('User')); LLIT.Width := 150; LLIT := TListItemText(LLVI.Objects.FindDrawable('Typ')); LLIT.PlaceOffset.X := 250; LLIT.Width := 143; end; end else begin Toast('Landscape'); for LLVI in lvInventar.Items do begin LLIT := TListItemText(LLVI.Objects.FindDrawable('User')); LLIT.Width := 300; LLIT := TListItemText(LLVI.Objects.FindDrawable('Typ')); LLIT.PlaceOffset.X := 400; LLIT.Width := 428; end; end; end; Ich bedanke mich schon einmal im Voraus! PS: Umgebung: RAD Studio 10.1 Berlin Testgerät: Samsung Galaxy S8 Plus (kein Emulator) |
AW: FMX - ListView - ItemAppearance - Runtime
Delphi-Quellcode:
Also das Verschieben s.o. funktioniert bei mir.
LLIT.PlaceOffset.X := 250;
LLIT.Width := 143; Bist du sicher das es überhaupt in diese Funktion reinspringt ? Wenn das "OnResize" ist, damit hatte ich auch mal Probleme im Anfang. Kann sein das es jetzt wieder läuft in Rio, aber seitdem benutze ich für Portrait/Landscape nur noch die ApplicationEvents statt OnResize. |
AW: FMX - ListView - ItemAppearance - Runtime
Hey Rollo, danke für die schnelle Antwort.
Ich habe es wie folgt eingebunden:
Delphi-Quellcode:
Der Event wird beim drehen des Displays auch getriggert (habe ich mir via Toast ausgeben lassen). Aber die TListItemText ändern sich leider nicht.
TfMain = class(TForm)
... private FOrientationChangedId: Integer; procedure OnOrientationChanged(const Sender: TObject; const Msg: TMessage); end; … … procedure TfMain.FormCreate(Sender: TObject); begin FOrientationChangedId := TMessageManager.DefaultManager.SubscribeToMessage(TOrientationChangedMessage, OnOrientationChanged); end; procedure TfMain.OnOrientationChanged(const Sender: TObject; const Msg: TMessage); var LLIT: TListItemText; LLVI: TListViewItem; LSS : IFMXScreenService; begin if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(LSS)) then begin if LSS.GetScreenOrientation in [TScreenOrientation.soPortrait, TScreenOrientation.soInvertedPortrait] then begin Toast('Portrait'); for LLVI in lvInventar.Items do begin LLIT := TListItemText(LLVI.Objects.FindDrawable('User')); LLIT.Width := 150; LLIT := TListItemText(LLVI.Objects.FindDrawable('Typ')); LLIT.PlaceOffset.X := 250; LLIT.Width := 143; end; end else begin Toast('Landscape'); for LLVI in lvInventar.Items do begin LLIT := TListItemText(LLVI.Objects.FindDrawable('User')); LLIT.Width := 300; LLIT := TListItemText(LLVI.Objects.FindDrawable('Typ')); LLIT.PlaceOffset.X := 400; LLIT.Width := 428; end; end; end; Allerdings habe ich just in diesem Moment eine Lösung gefunden. Allerdings weiß ich nicht, warum das jetzt funktioniert: Ich befülle die ListView bei jedem Triggern neu, und erstelle die TListViewText per Code mit den entsprechenden Werten. Das funktioniert nun super und (überraschenderweise) auch schnell! Verstehen tu ich es allerdings überhaupt nicht! :oops: |
AW: FMX - ListView - ItemAppearance - Runtime
Du kannst ja auch Debuggen, dann siehst du wo genau er hinkommt und wo nicht.
Den Toast würde ich mir sparen. Leg duch einfach mal zum Test zwei Buttons mit auf die Form, welche das Verschieben Portrait und Landscape simulieren (ohne Application-Events). Damit kann ich hier die Texte anpassen. Bin mir jetzt nicht sicher ob die Application-Events im Thread laufen. Du kannst ja mal um die Funktionen die deine Texte anfassen ein TThread.Synchronize legen, zum Testen.
Delphi-Quellcode:
TThread.Synchronize(
nil, procedure begin // Nur hier die Listview anfassen end ); |
AW: FMX - ListView - ItemAppearance - Runtime
Ich mache das über den Toast, weil ich Android 8.0.0 verwende, auf der (zumindest laut Google) nicht debugt werden kann.
Das Anpassen der Texte funktioniert bei mir auch super, aber nicht das Ändern von Width/Height/PlaceOffset. Aber wie gesagt, funktioniert es mit dem Neuerstellen beim Wechsel der Orientation sehr gut. |
AW: FMX - ListView - ItemAppearance - Runtime
Schon mal probiert, vor der Änderung der ListviewItems ein Beginupdate und danach Endupdate (also bei der Listview selber, lvInventar) zu setzen?
Mal abgesehen davon, ob das hier hilft, wäre es aus Performance-Gründen jedenfalls immer bei solchen Zugriffen geboten. |
AW: FMX - ListView - ItemAppearance - Runtime
Moin,
stand gerade einem sehr ähnlichen Problem. Ich hatte ein Listview mit DynamicAppearance designed und wollte, dass die Spaltenbreiten sich vergrößern, wenn man im Querformat ist. Bei ItemDetailAppearance braucht man nur:
Code:
Bei DynamicAppearance muss man das Objekt raussuchen und es verändern:
lv.ItemAppearanceObjects.ItemObjects.Text.PlaceOffset.X:=0;
lv.ItemAppearanceObjects.ItemObjects.Text.Width:=lv.Width-2; lv.ItemAppearanceObjects.ItemObjects.Detail.PlaceOffset.X:=(lv.Width / 2); lv.ItemAppearanceObjects.ItemObjects.Detail.Width:=(lv.Width /2)-2;
Code:
Ich sehe gerade, der Eintrag ist uralt, aber was solls. Hab ich auch mal ne Lösung beigesteuert ;-)
procedure TfMain.lvPosResized(Sender: TObject);
var ta:tTextObjectAppearance; function FindIt(aName:String):tTextObjectAppearance; var ca:TCommonObjectAppearance; begin result:=nil; with lvPos do begin for ca in ItemAppearanceObjects.ItemObjects.Objects do begin if comparetext(ca.Name,aName)=0 then begin result:=ca as tTextObjectAppearance; exit; end; end; end; end; begin with lvPos do begin ta:=FindIt('Text'); if ta<>nil then begin ta.Width:=Width-80; end; ta:=FindIt('Detail'); if ta<>nil then begin ta.Width:=Width-80; end; end; |
AW: FMX - ListView - ItemAppearance - Runtime
Zitat:
-- LG aus dem hohen Norden, Edmund |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz