[英]Animating the addition of a string to a ListBox in FireMonkey
The following code nicely animates adding a new string to the end of a ListBox 以下代码很好地动画将新字符串添加到ListBox的末尾
procedure TForm6.AddItem(s: string);
var
l : TListBoxItem;
OldHeight : Single;
begin
l := TListBoxItem.Create(Self);
l.Text := s;
OldHeight := l.Height;
l.Height := 0;
l.Parent := ListBox1;
l.Opacity := 0;
l.AnimateFloat('height', OldHeight, 0.5);
l.AnimateFloat('Opacity', 1, 0.5);
end;
The item expands and fades in. However I want to be able to add the string into an arbitrary location in the ListBox - actually at the current ItemIndex. 该项扩展和淡入。但是我希望能够将字符串添加到ListBox中的任意位置 - 实际上是在当前的ItemIndex。 Does anyone know how to do this? 有谁知道如何做到这一点?
To work around the fact that ListBox1.InsertObject
and ListBox1.Items.Insert
don't work you can do the following 要解决ListBox1.InsertObject
和ListBox1.Items.Insert
不起作用的事实,您可以执行以下操作
procedure TForm1.AddItem(s: string);
var
l : TListBoxItem;
OldHeight : Single;
I: Integer;
index : integer;
begin
l := TListBoxItem.Create(nil);
l.Text := s;
OldHeight := l.Height;
l.Height := 0;
l.Opacity := 0;
l.Index := 0;
l.Parent := ListBox1;
Index := Max(0, ListBox1.ItemIndex);
for I := ListBox1.Count - 1 downto Index + 1 do
begin
ListBox1.Exchange(ListBox1.ItemByIndex(i), ListBox1.ItemByIndex(i-1));
end;
ListBox1.ItemIndex := Index;
l.AnimateFloat('height', OldHeight, 0.5);
l.AnimateFloat('Opacity', 1, 0.5);
end;
but is a bit ridiculous. 但有点荒谬。 It (eventually) adds the string in position 0 if there is no item selected, otherwise adds it before the selected item. 如果没有选择项目,它(最终)将字符串添加到位置0,否则在所选项目之前添加它。 This solution reminds me too much of Bubble Sort . 这个解决方案让我想起了Bubble Sort 。 You will need to add the math unit to your uses clause for the max function to work. 您需要将数学单元添加到uses子句中才能使max函数起作用。
This does indeed seem to be a bug in FireMonkey (check Quality Central #102122 ), However I suspect a future FireMonkey update will fix this. 这确实似乎是FireMonkey中的一个错误(检查Quality Central #102122 ),但我怀疑未来的FireMonkey更新会解决这个问题。 If anyone can see a better way of doing this.... 如果有人能看到更好的方法来做到这一点......
I've also made a movie about this for those who are interested, which illustrates things more clearly. 我也为那些感兴趣的人制作了一部关于这个的电影 ,它更清楚地说明了事情。
This should work, but it does nothing: 这应该有效,但它什么都不做:
l := TListBoxItem.Create(ListBox1);
ListBox1.InsertObject(Max(ListBox1.ItemIndex, 0), l);
If I then call the following, I get an access violation: 如果我然后调用以下内容,则会出现访问冲突:
ListBox1.Realign;
In fact, even this gives me an AV: 事实上,即使这给了我一个AV:
ListBox1.Items.Insert(0, 'hello');
ListBox1.Realign;
But this adds one, of course: 但是这当然会增加一个:
ListBox1.Items.Add('hello');
A bug perhaps? 也许是一个错误?
Instead of 代替
l.Parent := ListBox1;
use 使用
ListBox1.InsertObject(Index, l);
where Index is the insertion position. 其中Index是插入位置。
(Untested but from reading the sources it should work). (未经测试,但从阅读它应该工作的来源)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.