Delphi / Firemonkey使Listboxses更好地同步滚动

时间:2015-09-17 13:19:41

标签: delphi firemonkey

我有一个非常脏的方式让7个列表框同步滚动,它们都具有完全相同的高度,所以当我移动其中任何一个的位置时,其他6也应移动到该位置

我所做的是滚动假设Listbox1并且 ViewportPositionChange()被解雇我说

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

这一切都有效,我只是将这个代码添加到每个Listboxses ViewportPositionChange()事件中,但它在Andriod上非常生涩和太慢,我仍然需要能够从任何一个列表框滚动但是没有办法改善滚动的性能?

老实说,它并不是非常慢,但你可以感觉它不是很活泼,而且每个列表框都可以有很多列表框,每个列表框也可以在这些控件中有一些控件和更多控件所以很多重新粉刷我想,这就是让它变得不那么活泼的原因。

示例代码

首先在表单上放置一个Gridpanel布局,添加6列并为每个列添加一个列表框,每个Listbox代表一天,Listbox 1是星期一,同时将这些列对齐到客户端。

全局变量

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

表单创建

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

现在每个列表框 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;

然后添加一个包含以下代码的按钮:

 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;

在listboxitem中有时可能会有更多的控件但通常我认为这将是常态,现在添加一些项目并尝试滚动

1 个答案:

答案 0 :(得分:0)

FMX TListBox有很多开销,因为每个列表框项基本上都是插入到滚动框中的样式组件。这有利于灵活性,但对速度不利。

在Windows和OSX中,有一些函数,如ScrollWindowEx或NSView.scrollRect + NSView.setNeedsDisplayInRect,可以通过滚动窗口的一部分而不发出绘制消息来帮助提高性能。因此,您只需要使列表框的一部分无效。我可以想象Android有类似的东西。但是你可能不得不修补FMX才能使用它。这可以稍微改善性能,但仍然不是一个出色的性能魔术开关。类似的方法是在位图中缓存滚动框的内容,然后在滚动时将部分位图复制到屏幕。

如果您需要非常好的列表框性能,那么您需要开发自己的列表框,该列表框针对速度进行了优化。这是我必须为我的应用程序的OSX版本做的,以获得我需要的性能。