0
votes

I have a very dirty way of having 7 listboxses scroll in sync, they all have the exact same height so when I move the position of any one of them the other 6 should also move to that position

What I do is Assume Listbox1 is scrolled and ViewportPositionChange() is fired I say

Listbox2.ViewportPosition := NewViewportPosition;
Listbox3.ViewportPosition := NewViewportPosition;

And this all works and I just add this code to each Listboxses ViewportPositionChange() event, but its terribly jerky and too slow on Andriod, I still need to be able to scroll from any one listbox but is there not a way to improve the performace of the scroll?

Ok to be honest it isn't terribly slow but you can feel its not exactly snappy, and also each listbox can have lots of listboxses and each listbox can also have a few controls and more controls in those controls so alot of repainting is done I think and this is what is making it less snappy.

Sample code

Firstly place a Gridpanel layout on your form, Add 6 columns And add a listbox to each, each Listbox represents a day, where Listbox 1 is Monday, Also Align these to client.

Global variables

private Glistbox : array[0..6] of TListBox;

On form Create

Glistbox[0] := ListBox1;
Glistbox[1] := ListBox2;
Glistbox[2] := ListBox3;
Glistbox[3] := ListBox4;
Glistbox[4] := ListBox5;
Glistbox[5] := ListBox6;
Glistbox[6] := ListBox7;

And now on each listboxses OnViewportPositionChange

//Note that this would be for Listbox1 so for listbox 2 it needs to be changed acordingly
ListBox2.ViewportPosition := NewViewportPosition;
ListBox3.ViewportPosition := NewViewportPosition;
ListBox4.ViewportPosition := NewViewportPosition;
ListBox5.ViewportPosition := NewViewportPosition;
ListBox6.ViewportPosition := NewViewportPosition;
ListBox7.ViewportPosition := NewViewportPosition;

Then add a button with the following code :

 var
    mainlayout,item1,item2 : Tlayout;
    listboxitem : TListBoxItem;
    myrec,myrec2 : TRectangle;
    lbl1,lbl2 : TLabel;
    I: Integer;
begin
for I := 0 to 6 do
begin
    listboxitem := TListBoxItem.Create(nil);

    mainlayout := TLayout.Create(nil);
    mainlayout.Align := TAlignLayout.Client;
    mainlayout.Parent:= listboxitem;

    item1 := TLayout.Create(nil);
    item1.Align:= TAlignLayout.Left;
    item1.Parent := mainlayout;

    item2 := TLayout.Create(nil);
    item2.Align:= TAlignLayout.Right;
    item2.Parent := mainlayout;

    myrec := TRectangle.Create(nil);
    myrec.Align := TAlignLayout.Client;
    myrec.Parent := item1;

    myrec2 := TRectangle.Create(nil);
    myrec2.Align := TAlignLayout.Client;
    myrec2.Parent := item2;

    lbl1 := TLabel.Create(nil);
    lbl1.Align := TAlignLayout.Client;
    lbl1.TextAlign := TTextAlign.Center;
    lbl1.Text := '1';
    myrec.AddObject(lbl1);

    lbl2 := TLabel.Create(nil);
    lbl2.Align := TAlignLayout.Client;
    lbl2.TextAlign := TTextAlign.Center;
    lbl2.Text := '2';
    myrec2.AddObject(lbl2);

    Glistbox[I].AddObject(listboxitem);
    item2.Width:= mainlayout.Width/2;
end;

There could sometimes be more controls in a listboxitem but generally I think this would be the norm, Now add a few items and try the scroll

1
Have you considered using a grid control with seven columns?Rob Kennedy
Unfortunately I have been down the rabbit hole too far to change to a grid control without changing too much other code, like I said its not snappy but it is workable for nowPeter-John Jansen
In other words, you've already decided that you don't want to consider other options. In which case, why ask the question. At the very least be honest about it. Say that you can't face changing the design, but is there some magic switch that makes you app super swanky. Like Application.AwesomeScrolling := True.David Heffernan
I am willing to change design but I wanted to know first if there isn't a somewhat helpful practice that I can try like Using BeginUpdate and EndUpdate when adding Listbox items before changing design, basically anything basic that I might have missed that could improve the current design, if my only option is a grid control then that is fine, It will at some stage then change to thatPeter-John Jansen
Fair enough. I think it would make it easier for you to receive help if it was possible for us to reproduce the behaviour. As it stands, we'd have to try to build you app from scratch based on the loose description in the question. That's not appealing because we'd have to invest significant time with no guarantee that we'd end up with your app.David Heffernan

1 Answers

0
votes

The FMX TListBox has a lot of overhead because every listbox item basically is a styled component that is inserted into a scrollbox. This is good for flexibility, but bad for speed.

In Windows and OSX there is functions like ScrollWindowEx or NSView.scrollRect + NSView.setNeedsDisplayInRect that can help improve performance by scrolling a part of the window without issuing paint messages. So you'd only have to invalidate a part of the listbox. I could imagine that Android has something similar. But you'll likely have to patch FMX in order to use that. This can improve performance a bit, but is still not a magic switch for great performance. A similar approach would be caching the content of the scrollbox in a bitmap and then copy parts of the bitmap to the screen while scrolling.

If you need really good listbox performance then you'll need to develop your own listbox that is optimized for speed. This is what I had to do for the OSX version of my application in order to get the performance I needed.