You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Delphi FireMonkey中的TRectangle组件设置Touch Target Expansion

在FMX中给TRectangle实现触摸目标扩展的几种方案

嗨,我刚好在FMX项目里处理过类似的需求——用TRectangle当按钮但缺TouchTargetExpansion属性,给你几个实用的解决办法:

方案1:重写TRectangle的HitTest方法(自定义组件,适合复用)

这是最正规的做法,自定义一个带触摸扩展属性的Rectangle,以后可以在多个项目里直接复用。

步骤很简单:

  1. 新建一个组件单元,继承TRectangle,添加TouchTargetExpansion属性
  2. 重写HitTest方法,让它判断触摸点是否在扩展后的矩形范围内

下面是完整的Delphi代码示例:

unit CustomTouchRectangle;

interface

uses
  System.Classes, FMX.Types, FMX.Controls, FMX.StdCtrls;

type
  TCustomTouchRectangle = class(TRectangle)
  private
    FTouchTargetExpansion: Integer;
    function GetExpandedAbsoluteRect: TRectF;
  protected
    function HitTest(const Point: TPointF; const AllowDisabled: Boolean): Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    // 添加和标准组件一致的触摸扩展属性
    property TouchTargetExpansion: Integer read FTouchTargetExpansion write FTouchTargetExpansion default 0;
  end;

implementation

{ TCustomTouchRectangle }

constructor TCustomTouchRectangle.Create(AOwner: TComponent);
begin
  inherited;
  FTouchTargetExpansion := 0;
end;

function TCustomTouchRectangle.GetExpandedAbsoluteRect: TRectF;
begin
  // 获取控件的绝对位置,然后向四个方向扩展
  Result := Self.AbsoluteRect;
  Result.Inflate(FTouchTargetExpansion, FTouchTargetExpansion);
end;

function TCustomTouchRectangle.HitTest(const Point: TPointF; const AllowDisabled: Boolean): Boolean;
begin
  if FTouchTargetExpansion <= 0 then
    // 没有扩展时,用默认的HitTest逻辑
    Result := inherited HitTest(Point, AllowDisabled)
  else
    // 有扩展时,判断触摸点是否在扩展后的矩形内,同时保留启用状态判断
    Result := GetExpandedAbsoluteRect.Contains(Point) and (AllowDisabled or Enabled);
end;

end.

写完这个单元后,把组件注册到IDE里,你就能像用普通TRectangle一样,在属性面板里设置TouchTargetExpansion的值(比如设为15,触摸范围就向外扩展15像素)。

方案2:用父容器间接实现(无需编码,快速见效)

如果只是临时用一下,不想写自定义组件,这个方法最省事:

  • 拖一个TLayout(或者TPanel)到窗体上,设置它的Padding来控制扩展范围(比如Padding上下左右都设为10)
  • 把你的TRectangle放到这个Layout里,设置Align=Client让它填满Layout的内容区域
  • 把Layout的HitTest设为True,TRectangle的HitTest设为False
  • 给Layout添加你需要的事件(比如OnClick、OnMouseDown)

这样一来,点击Layout的任何区域(包括Padding的扩展部分)都会触发事件,相当于间接给TRectangle扩展了触摸目标。我在做原型的时候经常用这个方法,不用写一行代码就能搞定。

方案3:手势管理器辅助(进阶场景)

如果你的需求更复杂(比如需要区分不同的触摸手势),可以用FMX的TGestureManager:

  1. 给窗体添加一个TGestureManager组件
  2. 把TRectangle的GestureManager属性关联到这个组件
  3. 处理TRectangle的OnGesture事件,在事件里判断触摸点是否在扩展后的矩形范围内

不过这个方法相对繁琐,一般只有在需要手势识别的时候才用,普通的按钮场景还是前两个方案更合适。


内容的提问来源于stack exchange,提问作者codeGood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:27:40