首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FireMonkey控件不能平稳地运行。

FireMonkey控件不能平稳地运行。
EN

Stack Overflow用户
提问于 2011-12-07 06:13:24
回答 1查看 3.5K关注 0票数 9

背景

我使用一些FireMonkey控件创建了一个GUI。

  • 有些控件是动画的,它们的外观会自动更新。
  • 一些控件仅针对用户交互(滑块等)进行更新。

问题

与用户控件的交互阻止对动画控件的更新,从而导致不连续的动画。

浮躁动画视频

以上视频中的动画控件是由TTimer组件驱动的。当使用FireMonkey的动画组件时,问题仍然存在。

Investigation

滑块控件在调整后调用Repaint()。平滑地调整滑块将生成重绘()调用的密集流,从而阻止其他控件被更新。

怎么办?

冻结动画,而一个控件是不断更新是不适合我的应用程序。我的第一个想法是将重新画图()调用交换为类似于Invalidate()方法的调用,但是FireMonkey没有任何类似的AFAIK。

这个问题有什么好的解决办法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-08 00:42:09

我已经创建了一个基于计时器的重绘方法,正如上面的注释中所建议的那样。到目前为止,它似乎起作用了。

代码语言:javascript
复制
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.

==

使用

可以通过调用以下命令重新绘制控件:

代码语言:javascript
复制
InvalidateControl(MyControl);

InvalidateControl()过程不会立即重新绘制控件。相反,它将控件添加到列表中。全局计时器稍后会检查列表,调用removes ()并从列表中移除控件。使用此方法,可以根据需要将控件失效,但不会像快速重绘()调用那样阻止其他控件进行更新。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8411143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档