[FMX]在程序中使用已有的样式做自己需要的渲染

今天我们来做一件坏事,我们都是坏孩子……

我们知道,FMX 是有 StyleBook,每个控件有自己的样式,但有时候,我们要绘制自绘一些状态,难道非要用户重新定义一堆样式吗?为啥不能利用现成的样式呢,比如,我就只是要自绘一个CheckBox,但我还不想放置一个TCheckBox组件,那么怎么来做呢?

第一:我们需要知道 TCheckBox 使用的样式名称, 按照官方的命名规则,它是去掉 T,变小写,然后再加 style,也就是说,样式的名称为 checkboxstyle。

第二:我们需要知道我们要找的样式的名称,对于 CheckBox,它是 background,当然你也可以不要去管它,你按类型来找,比如这里是它子对象中类型为 TCheckStyleObject 类型的对象。

第三:如果我们是通过名称来找的话,就需要判断下是不是对应的样式对象,如果不是,就不能继续了,如果是才能继续。如果是的话,我们就可以调用样式对象的 DrawToCanvas 方法,将其绘制到目标画布上了。

到了这一步,我们就画出了一个简单的复选框,但是如果我们要绘制一个选中的复选框怎么办?继续

第四:我们要添加一个IsChecked 属性,当然如果是别的属性(布尔值),你就需要设置 TCheckStyleObject 对象的 ActiveTrigger,设置后调用 StartTriggerAnimation 来启用这个触发器,比如 IsChecked。

第五:回到第三步,绘制到画布上就好了。

简单的参考代码如下:

uses fmx.styles.objects;
{$R *.fmx}

procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
var
  ARes: TFMXObject;
  AStyle: TCheckStyleObject;
begin
  ARes := TStyledControl.LookupStyleObject(nil, nil, Self, 'checkboxstyle', '',
    '', false);
  ARes := ARes.FindStyleResource('background', true);
  if Assigned(ARes) and (ARes is TCheckStyleObject) then
  begin
    AStyle := TCheckStyleObject(ARes as TCheckStyleObject);
    AStyle.StartTriggerAnimation(Self, 'IsChecked');//只绘制普通的选择框不需要它,更具体请看 Delphi 自己的源码实现
    AStyle.DrawToCanvas(Canvas, RectF(10, 10, 10 + AStyle.Width,
      10 + AStyle.Height));
  end;
end;

function TForm1.GetIsChecked: Boolean;
begin
  Result := true;
end;

当然了,如果嫌这里调用 StartTrigger 麻烦,直接修改其私有的 FState 成员就得了,具体方法,参考以前的文章。

好吧,附个图,有图有真相:

分享到: