如何为Delphi FireMonkey中的TRectangle组件设置Touch Target Expansion
在FMX中给TRectangle实现触摸目标扩展的几种方案
嗨,我刚好在FMX项目里处理过类似的需求——用TRectangle当按钮但缺TouchTargetExpansion属性,给你几个实用的解决办法:
方案1:重写TRectangle的HitTest方法(自定义组件,适合复用)
这是最正规的做法,自定义一个带触摸扩展属性的Rectangle,以后可以在多个项目里直接复用。
步骤很简单:
- 新建一个组件单元,继承TRectangle,添加
TouchTargetExpansion属性 - 重写
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:
- 给窗体添加一个
TGestureManager组件 - 把TRectangle的
GestureManager属性关联到这个组件 - 处理TRectangle的
OnGesture事件,在事件里判断触摸点是否在扩展后的矩形范围内
不过这个方法相对繁琐,一般只有在需要手势识别的时候才用,普通的按钮场景还是前两个方案更合适。
内容的提问来源于stack exchange,提问作者codeGood
相关产品推荐
相关产品推荐

