Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   FMX - ListView - ItemAppearance - Runtime (https://www.delphipraxis.net/199614-fmx-listview-itemappearance-runtime.html)

sintronic86 6. Feb 2019 09:53

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:
TMessageManager.DefaultManager.SubscribeToMessage(TOrientationChangedMessage, OnOrientationChanged);
ausprobiert.

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:
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;
Hat jemand von euch eine Idee dazu?
Ich bedanke mich schon einmal im Voraus!


PS:
Umgebung: RAD Studio 10.1 Berlin
Testgerät: Samsung Galaxy S8 Plus (kein Emulator)

Rollo62 6. Feb 2019 11:19

AW: FMX - ListView - ItemAppearance - Runtime
 
Delphi-Quellcode:
        LLIT.PlaceOffset.X := 250;
        LLIT.Width := 143;
Also das Verschieben s.o. funktioniert bei mir.
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.

sintronic86 6. Feb 2019 11:37

AW: FMX - ListView - ItemAppearance - Runtime
 
Hey Rollo, danke für die schnelle Antwort.

Ich habe es wie folgt eingebunden:

Delphi-Quellcode:
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;
Der Event wird beim drehen des Displays auch getriggert (habe ich mir via Toast ausgeben lassen). Aber die TListItemText ändern sich leider nicht.


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:

Rollo62 6. Feb 2019 12:48

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
);

sintronic86 7. Feb 2019 15:25

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.

Harry Stahl 7. Feb 2019 16:29

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.

michaelg 17. Feb 2021 13:59

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:
  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;
Bei DynamicAppearance muss man das Objekt raussuchen und es verändern:
Code:
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;
Ich sehe gerade, der Eintrag ist uralt, aber was solls. Hab ich auch mal ne Lösung beigesteuert ;-)

Poelser 17. Feb 2021 14:10

AW: FMX - ListView - ItemAppearance - Runtime
 
Zitat:

Zitat von michaelg (Beitrag 1483198)
Ich sehe gerade, der Eintrag ist uralt, aber was solls. Hab ich auch mal ne Lösung beigesteuert ;-)

Von Februar 2019? Das ist doch noch nicht alt! Da haben einige schon Knochen ausgegraben... :zwinker:
--
LG aus dem hohen Norden, Edmund


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz