Einzelnen Beitrag anzeigen

Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#19

AW: Listview mit Firemonkey

  Alt 5. Mai 2016, 12:02
Ich habe meine beiden weiter oben gemachten Vorschläge mal umgesetzt und hab somit Deinen Beispielcode etwas geändert und im Painting-Event Source eingefügt, der die Bitmaps quasi "on the fly" erzeugt.

Maximal leben immer nur 60 Bitmaps zur gleichen Zeit, abhängig von der Variable Range, die Du halt bei Bedarf ändern kannst. Der Speicher wird also kaum belastet.

So wird die Liste quasi ohne Verzögerung erstellt und auch das Zeichnen erfolgt ohne Verzögerung (jedenfalls auf dem PC, wie es auf dem mobilen Teil ist, musst Du selber ausprobieren, hab hier gerade nichts im Zugriff zum Testen --> Hier wäre eine kurze Rückmeldung von Interesse).

Delphi-Quellcode:
procedure TForm19.Button1Click(Sender: TObject);
var
   i: integer;
   item: TListViewItem;
begin
   ListView1.BeginUpdate;
   for i := 0 to 4000 do
   begin
     item := ListView1.Items.Add;
     item.Text := format('channel %d', [i]);
     item.Detail := 'lorem ipsum' + sLineBreak + 'lorem ipsum';
// item.Bitmap.SetSize(128,128);
// item.Bitmap.Clear (TAlphaColorRec.red);
   end;
   ListView1.EndUpdate;
end;

procedure TForm19.ListView1Painting(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
var
  lvi: TListViewItem;
  L, start, stop, range, TopItem: Integer;
begin
  if Listview1.ItemCount = 0 then exit;

  range := 20;

  TopItem := Round (Listview1.ScrollViewPos / Listview1.ItemAppearance.ItemHeight);

  Start := TopItem;
  Stop := Start + range;

  for L := Start to Stop-1 do begin
    if L <= Listview1.ItemCount-1 then begin
      lvi := Listview1.Items[L];

      if lvi.Bitmap.Width = 0 then begin
         lvi.Bitmap.SetSize(128,128);
         lvi.Bitmap.Clear (TAlphaColorRec.red);
      end;
    end;
  end;

  // Bei Bedarf

  if Start > 50 then begin
    for L := Start-20 downto 0 do begin
      lvi := Listview1.Items[L];

      if lvi.Bitmap.Width <> 0 then begin
        lvi.Bitmap.SetSize(0,0);
      end;
    end;
  end;

  if Stop + 20 <= Listview1.ItemCount-1 then begin
    for L := Stop + 20 to Listview1.ItemCount-1 do begin
      lvi := Listview1.Items[L];

      if lvi.Bitmap.Width <> 0 then begin
        lvi.Bitmap.SetSize(0,0);
      end;
    end;
  end;
end;
Anliegend ein Screenshot und das Demo-Projekt (mit Delphi Seattle erstellt).

Edit: Habe doch noch ein mobiles Teil gefunden (Samsung GT-N5100) und schnell mal selbst geteset. Das funktioniert absolut flüssig, null Verzögerung, dabei ist das Gerät noch nicht mal das schnellste. Man sollte aber für Range mehr als 20 Zeilen wählen, da auf größeren Geräten diese Anzahl schnell erreicht ist. 40-60 wären da wohl besser.

Edit2: Wenn ich es mir genau überlege, könnte man die benötigte Range (also Anzahl der ListItems, die in der ListView maximal zur gleichen Zeit sichtbar sind) auch anhand der Höhe der Listview berechnen.
Miniaturansicht angehängter Grafiken
onthefly.jpg  
Angehängte Dateien
Dateityp: zip ManyImages.zip (53,9 KB, 15x aufgerufen)

Geändert von Harry Stahl ( 5. Mai 2016 um 12:32 Uhr)
  Mit Zitat antworten Zitat