我正在颤动的画布上绘制文本和其他对象。
我想检测鼠标何时悬停在画布上呈现的某些文本上。
TextSpan 类具有recognizer
以及onEnter
和的属性onExit
。
当在画布上绘制文本跨度时,它们似乎没有被调用。
我是否需要自己为 Canvas 上的文本编写命中测试逻辑?
我正在颤动的画布上绘制文本和其他对象。
我想检测鼠标何时悬停在画布上呈现的某些文本上。
TextSpan 类具有recognizer
以及onEnter
和的属性onExit
。
当在画布上绘制文本跨度时,它们似乎没有被调用。
我是否需要自己为 Canvas 上的文本编写命中测试逻辑?
我找不到按照您的意愿执行此操作的方法,但是我已经能够使用不同的方法来执行此操作。在这个例子中,我CustomPaint
用 a包装MouseRegion
(因为我用颤振网络测试它,你可以用InkWell
or为手机重新创建它GestureDetector
),然后我检查鼠标的 localPosition 是否在TextPainter
. 我正在创建TextPainter
外部CustomPainter
,因为我希望整个画布的大小是TextPainter
' 的两倍。
class GestureText extends StatefulWidget {
const GestureText(this.text, {required this.style, this.maxWidth, Key? key})
: super(key: key);
final String text;
final TextStyle style;
final double? maxWidth;
@override
_GestureTextState createState() => _GestureTextState();
}
class _GestureTextState extends State<GestureText> {
Offset? mousePosition;
@override
Widget build(BuildContext context) {
final TextPainter textPainter = TextPainter(
text: TextSpan(
text: widget.text,
style: widget.style,
),
textDirection: TextDirection.ltr,
)..layout(maxWidth: widget.maxWidth ?? double.infinity);
return Container(
child: MouseRegion(
onHover: (e){
setState(() {
mousePosition = e.localPosition;
});
},
onExit: (e){
setState(() {
mousePosition = null;
});
},
child: CustomPaint(
size: Size(textPainter.size.width*2, textPainter.size.width*2),
painter: GestureTextPainter(textPainter, mousePosition),
),
),
);
}
}
class GestureTextPainter extends CustomPainter {
const GestureTextPainter(this.textPainter, this.mousePosition);
final TextPainter textPainter;
final Offset? mousePosition;
@override
void paint(Canvas canvas, Size size) {
final textOffset = Offset(size.width/2 - textPainter.width/2, size.height/2 - textPainter.height/2);
// So that the text is in the middle of the canvas
final textRect = Rect.fromLTWH(textOffset.dx, textOffset.dy, textPainter.width, textPainter.height);
if(mousePosition != null && textRect.contains(mousePosition!)){
canvas.drawRect(textRect, Paint()..color=Colors.amber);
}
textPainter.paint(canvas, textOffset);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}