[教程]QAnimation 使用教程之一:为 TPageControl 切换加入动画效果

首先,VCL 的 TPageControl 是没有切入切出动画的,所以,这里要做的是给 VCL 的 TPageControl 做动画支持。当然,虽然咱们说的是 QAnimation 教程,但关注的重点不是 QAnimation,而是如何给 TPageControl 添加动画效果,QAnimation 只是一个动画控制器而已,你完全可以用自己的 Timer 来替代。

第一步:当然是为 PageControl 创建 N 个 TabSheet 页面,这一步我们省略说明。

第二步:加入动画控制代码。

  1. 引用 qdac_ani 单元,或者在界面上加上你的 Timer,然后在你的 Timer 的 OnTimer 事件中处理动画。
  2. 我这个 Demo 是要求不断的切换,类似网页上常见的 slider 效果,所以我在 FormCreate 事件中添加处理代码:
    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, qdac_ani,
      Vcl.Imaging.pngimage, Vcl.ExtCtrls;
    
    type
      TForm1 = class(TForm)
        PageControl1: TPageControl;
        TabSheet1: TTabSheet;
        TabSheet2: TTabSheet;
        Label1: TLabel;
        Label2: TLabel;
        Edit1: TEdit;
        Image1: TImage;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        FAnimation: IQAnimation;
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    uses qstring;
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      I: Integer;
    begin
      for I := 0 to PageControl1.PageCount - 1 do
        PageControl1.Pages[I].TabVisible := false;
      PageControl1.ActivePage := TabSheet1;
      //创建动画控制器
      FAnimation := CreateAnimation(
        procedure(Sender: IQAnimation; AEvent: TQAnimationEvent)
        var
          APage: TTabSheet;
        begin
          case AEvent of
            GotoTime:
              begin
                //因为动画是将下一页切入,所以取当前活动页的下一页进行处理
                APage := PageControl1.Pages[(PageControl1.ActivePageIndex + 1)
                  mod PageControl1.PageCount];
                APage.SetBounds(PageControl1.ActivePage.Left,APage.Height - Trunc(APage.Height *
                  Sender.NormalizedTime),PageControl1.ActivePage.Width,PageControl1.ActivePage.Height);
              end;
            EnterDelay:
              begin
                APage := PageControl1.Pages[(PageControl1.ActivePageIndex + 1)
                  mod PageControl1.PageCount];
                APage.Align := alClient;
                PageControl1.ActivePage := APage;
              end;
            ExitDelay:
              begin
                 //因为动画是将下一页切入,所以取当前活动页的下一页进行处理
                APage := PageControl1.Pages[(PageControl1.ActivePageIndex + 1)
                  mod PageControl1.PageCount];
                //VCL的 TabSheet 默认是alClient,那样没法调整坐标,所以改下
                APage.Align := alNone;
                //不可见页实际上是隐藏的,设置为true显示出来
                APage.Visible := true;
                //动画页切到前面,后面谁也不知道呀
                APage.BringToFront;
              end;
          end;
        end);
      FAnimation.Duration := 1;//动画时长设置为1秒
      FAnimation.Interpolation := TQInterpolationType.Bounce;//动画方式设置为弹跳
      FAnimation.DelayTime := 5;//动画延迟间隔设置为5秒
      FAnimation.Loop := true;//循环
      FAnimation.Start;//启动动画
    end;

    QAnimation 提供了一个 CreateXXAnimation 的一组接口函数,方便创建不同类型的动画。因为这个控制操作相对复杂一些,所以我直接用了 CreateAnimation,自己去实现对页面属性的控制。然后上面的动画控制参数都有说明,我就不缀述,自己看下就好。重点大家关注下对页面切换的处理,在我们开始切入新页时,要将新页的 Align 设置为 alNone,否是你调整坐标是动不起来的,然后还需要将要新页给提到最前显示,否则在后边用户也看不到,对不对?至于动画过程中,实际上就是直接调整的顶部的坐标,然后实现的动画方式是弹跳的效果。看一下实际运行的效果:

    QAnimation 提供的额外动画控制单元包含下面的函数,见名知义,不做多说:

    // 最简单的用户自定义处理动画
    function CreateAnimation(ACallback: TQAnimationNotifyCallback)
      : IQAnimation; overload;
    function CreateAnimation(ACallback: TQAnimationNotifyEvent)
      : IQAnimation; overload;
    // 浮点动画处理
    function CreateFloatAnimation(ACallback: TQAnimationNotifyCallback)
      : IQFloatAnimation; overload;
    function CreateFloatAnimation(ACallback: TQAnimationNotifyEvent)
      : IQFloatAnimation; overload;
    // 整数动画处理
    function CreateIntAnimation(ACallback: TQAnimationNotifyCallback)
      : IQIntAnimation; overload;
    function CreateIntAnimation(ACallback: TQAnimationNotifyEvent)
      : IQIntAnimation; overload;
    // 布尔动画处理
    function CreateBooleanAnimation(ACallback: TQAnimationNotifyCallback): IQBoolAnimation; overload;
    function CreateBooleanAnimation(ACallback: TQAnimationNotifyEvent): IQBoolAnimation; overload;
    // 颜色动画处理
    function CreateColorAnimation(ACallback: TQAnimationNotifyCallback)
      : IQColorAnimation; overload;
    function CreateColorAnimation(ACallback: TQAnimationNotifyEvent)
      : IQColorAnimation; overload;
    function CreateAlphaColorAnimation(ACallback: TQAnimationNotifyCallback)
      : IQAlphaColorAnimation; overload;
    function CreateAlphaColorAnimation(ACallback: TQAnimationNotifyEvent)
      : IQAlphaColorAnimation; overload;
    
    // 用户自定义控制特定属性的动画,具体的项目的值由用户自行决定
    function CreatePropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyCallback): IQPropertyAnimation; overload;
    function CreatePropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyEvent): IQPropertyAnimation; overload;
    
    function CreateIntPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyCallback): IQIntAnimation; overload;
    function CreateIntPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyEvent): IQIntAnimation; overload;
    
    function CreateFloatPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyCallback): IQFloatAnimation; overload;
    function CreateFloatPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyEvent): IQFloatAnimation; overload;
    
    function CreateColorPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyCallback): IQColorAnimation; overload;
    function CreateColorPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyEvent): IQColorAnimation; overload;
    
    function CreateAlphaColorPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyCallback): IQAlphaColorAnimation; overload;
    function CreateAlphaColorPropertyAnimation(AObject: TObject; APropPath: String;
      ACallback: TQAnimationNotifyEvent): IQAlphaColorAnimation; overload;

第三步:编译运行程序。

另外,QAnimation 不是免费的,价格暂定 99 元,FMX+VCL 同时支持,也就是说一套代码。你可以认为它是 FMX.Ani 的增强版,如果心疼的话,直接自己参考 FMX.Ani 单元写下就好。

分享到: