Currently, act.tap() taps the center of the RenderObject. But RenderParagraph can give the exact location of the text and there should be clicked, allowing TextSpans with gesture recognizers.
Offset locationOfTextSpan(String text) {
assert(text.length > 1);
final paragraph =
spotText(text).snapshotRenderObject() as RenderParagraph;
final fullText = paragraph.text.toPlainText();
final start = fullText.indexOf(text);
final end = start + text.length;
final barLocationStart =
paragraph.getOffsetForCaret(TextPosition(offset: start), Rect.zero);
final barLocationEnd =
paragraph.getOffsetForCaret(TextPosition(offset: end), Rect.zero);
if (barLocationStart.dy == barLocationEnd.dy) {
// on same line, click the middle
return Offset(
(barLocationStart.dx + barLocationEnd.dx) / 2,
(barLocationStart.dy + barLocationEnd.dy) / 2,
);
} else {
// click one pixel inside the first character
return barLocationStart + const Offset(1, 1);
}
}
Future<void> tapTextSpan(String text) async {
final spanLocation = locationOfTextSpan(text);
final binding = TestWidgetsFlutterBinding.instance;
final downEvent = PointerDownEvent(position: spanLocation);
binding.handlePointerEvent(downEvent);
final upEvent = PointerUpEvent(position: spanLocation);
binding.handlePointerEvent(upEvent);
}
Currently, act.tap() taps the center of the RenderObject. But
RenderParagraph
can give the exact location of the text and there should be clicked, allowing TextSpans with gesture recognizers.This example should be the default