背景
我使用一些FireMonkey控件创建了一个GUI。
问题
与用户控件的交互阻止对动画控件的更新,从而导致不连续的动画。
浮躁动画视频
以上视频中的动画控件是由TTimer组件驱动的。当使用FireMonkey的动画组件时,问题仍然存在。
Investigation
滑块控件在调整后调用Repaint()。平滑地调整滑块将生成重绘()调用的密集流,从而阻止其他控件被更新。
怎么办?
冻结动画,而一个控件是不断更新是不适合我的应用程序。我的第一个想法是将重新画图()调用交换为类似于Invalidate()方法的调用,但是FireMonkey没有任何类似的AFAIK。
这个问题有什么好的解决办法吗?
发布于 2011-12-08 00:42:09
我已经创建了一个基于计时器的重绘方法,正如上面的注释中所建议的那样。到目前为止,它似乎起作用了。
码
unit FmxInvalidateHack;
interface
uses
Fmx.Types;
procedure InvalidateControl(aControl : TControl);
implementation
uses
Contnrs;
type
TInvalidator = class
private
protected
Timer : TTimer;
List : TObjectList;
procedure Step(Sender : TObject);
public
constructor Create;
destructor Destroy; override;
procedure AddToQueue(aControl : TControl);
end;
var
GlobalInvalidator : TInvalidator;
procedure InvalidateControl(aControl : TControl);
begin
if not assigned(GlobalInvalidator) then
begin
GlobalInvalidator := TInvalidator.Create;
end;
GlobalInvalidator.AddToQueue(aControl);
end;
{ TInvalidator }
constructor TInvalidator.Create;
const
FrameRate = 30;
begin
List := TObjectList.Create;
List.OwnsObjects := false;
Timer := TTimer.Create(nil);
Timer.OnTimer := Step;
Timer.Interval := round(1000 / FrameRate);
Timer.Enabled := true;
end;
destructor TInvalidator.Destroy;
begin
Timer.Free;
List.Free;
inherited;
end;
procedure TInvalidator.AddToQueue(aControl: TControl);
begin
if List.IndexOf(aControl) = -1 then
begin
List.Add(aControl);
end;
end;
procedure TInvalidator.Step(Sender: TObject);
var
c1: Integer;
begin
for c1 := 0 to List.Count-1 do
begin
(List[c1] as TControl).Repaint;
end;
List.Clear;
end;
initialization
finalization
if assigned(GlobalInvalidator) then GlobalInvalidator.Free;
end.==
使用
可以通过调用以下命令重新绘制控件:
InvalidateControl(MyControl);InvalidateControl()过程不会立即重新绘制控件。相反,它将控件添加到列表中。全局计时器稍后会检查列表,调用removes ()并从列表中移除控件。使用此方法,可以根据需要将控件失效,但不会像快速重绘()调用那样阻止其他控件进行更新。
https://stackoverflow.com/questions/8411143
复制相似问题