本增强的目的是解决动画对象只支持 published 的有效的几种属性的问题,确切的说,这是一个适配器,通过匿名函数建立与非 published 属性的适配。我在 [FMX] Delphi 中 TAnimation 设计的几点值得商榷的地方 一文中讨论了 FMX 动画支持类的一些值得商榷的地方和改动,而这个增强从另一个角度来解决问题。
我们直接来看这个单元的全部源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
unit FMX.AniEh; // FMX.AniEh is a animation helper for unpublished property,create by QDAC swish and under freebsd license interface uses classes, fmx.types; type TGetValueProc<T> = reference to procedure(Sender: TObject; var AValue: T); TSetValueProc<T> = reference to procedure(Sender: TObject; const AValue: T); TAnimationHelper<T>=class(TFMXObject) private FOnSetValue : TSetValueProc<T>; FOnGetValue:TGetValueProc<T>; FSource:Pointer; function GetValue: T; procedure SetValue(const Value: T); public constructor Create(AOwner:TFMXObject;Source:Pointer;OnGetValue:TGetValueProc<T>;OnSetValue:TSetValueProc<T>); class function Bind(AOwner:TFMXObject;Source:Pointer;OnGetValue:TGetValueProc<T>;OnSetValue:TSetValueProc<T>):TAnimationHelper<T>; property Source:Pointer read FSource; published property Value:T read GetValue write SetValue; end; implementation { TAnimationHelper<T> } class function TAnimationHelper<T>.Bind(AOwner: TFMXObject; Source: Pointer; OnGetValue: TGetValueProc<T>; OnSetValue: TSetValueProc<T>): TAnimationHelper<T>; var I:Integer; begin for I:=AOwner.ComponentCount-1 downto 0 do begin if (AOwner.Components[I] is TAnimationHelper<T>) and (TAnimationHelper<T>(AOwner.Components[I]).Source=Source) then Exit(TAnimationHelper<T>(AOwner.Components[I])); end; Result:=TAnimationHelper<T>.Create(AOwner,Source,OnGetValue,OnSetValue); Result.SetRoot(AOwner.Root); end; constructor TAnimationHelper<T>.Create(AOwner:TFMXObject;Source: Pointer; OnGetValue: TGetValueProc<T>; OnSetValue: TSetValueProc<T>); begin inherited Create(AOwner); FSource:=Source; FOnGetValue:=OnGetValue; FOnSetValue:=OnSetValue; end; function TAnimationHelper<T>.GetValue: T; begin if Assigned(FOnGetValue) then FOnGetValue(Self,Result) else Result:=Default(T); end; procedure TAnimationHelper<T>.SetValue(const Value: T); begin if Assigned(FOnSetValue) then FOnSetValue(Self,Value); end; end. |
使用参考方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
procedure TfrmFunction.SpeedButton6Click(Sender: TObject); begin TAnimator.AnimateFloat(TAnimationHelper<Single>.Bind(HorzScrollBox1,nil, procedure (Sender:TObject;var V:Single) begin V:=HorzScrollBox1.ViewportPosition.X; end, procedure (Sender:TObject;const V:Single) begin HorzScrollBox1.ViewportPosition:=PointF(V,HorzScrollBox1.ViewportPosition.Y); end ),'Value',HorzScrollBox1.ViewportPosition.X+HorzScrollBox1.Width/2,0.5); end; |
THorzScrollBox 里原来 ViewportPosition 是没法设置动画的,现在通过它适配下就可以创建动画效果了。
0 条评论
沙发空缺中,还不快抢~