Created
February 4, 2021 06:54
-
-
Save suragch/a0a92ea4b8791202ea09ac9274a70670 to your computer and use it in GitHub Desktop.
Text affinity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
home: Scaffold( | |
body: HomeWidget(), | |
backgroundColor: Colors.white, | |
), | |
); | |
} | |
} | |
class HomeWidget extends StatefulWidget { | |
@override | |
_HomeWidgetState createState() => _HomeWidgetState(); | |
} | |
class _HomeWidgetState extends State<HomeWidget> { | |
@override | |
Widget build(BuildContext context) { | |
return Padding( | |
padding: const EdgeInsets.all(100.0), | |
child: CustomPaint( | |
size: Size(300, 300), | |
painter: LineWrappingAffinity(), | |
// painter: BidirectionalAffinity(), // <-- try this too | |
), | |
); | |
} | |
} | |
class LineWrappingAffinity extends CustomPainter { | |
@override | |
void paint(Canvas canvas, Size size) { | |
// text | |
const text = '0123456789'; | |
final textSpan = const TextSpan( | |
text: text, | |
style: TextStyle(fontSize: 50, color: Colors.black), | |
); | |
// draw text | |
final TextPainter textPainter = TextPainter() | |
..textDirection = TextDirection.ltr | |
..text = textSpan | |
..layout(maxWidth: 280); | |
textPainter.paint(canvas, Offset(0, 0)); | |
// draw cursor | |
final cursorPaint = Paint() | |
..color = Colors.red | |
..style = PaintingStyle.fill | |
..strokeWidth = 1; | |
var caretOffset = textPainter.getOffsetForCaret( | |
TextPosition(offset: 9, affinity: TextAffinity.upstream), | |
Rect.zero, | |
); | |
final dx = caretOffset.dx; | |
final dy = caretOffset.dy; | |
final rect = Rect.fromLTRB(dx, dy, dx + 3, dy + textPainter.height / 2); | |
canvas.drawRect(rect, cursorPaint); | |
} | |
@override | |
bool shouldRepaint(CustomPainter old) { | |
return false; | |
} | |
} | |
class BidirectionalAffinity extends CustomPainter { | |
@override | |
void paint(Canvas canvas, Size size) { | |
// text | |
const text = 'Helloשלום'; | |
final textSpan = const TextSpan( | |
text: text, | |
style: TextStyle(fontSize: 50, color: Colors.black), | |
); | |
// painters | |
final TextPainter textPainter = TextPainter() | |
..textDirection = TextDirection.ltr | |
..text = textSpan | |
..layout(); | |
final cursorPaint = Paint() | |
..color = Colors.red | |
..style = PaintingStyle.fill | |
..strokeWidth = 1; | |
// loop through each caret offset | |
var dy = 0.0; | |
for (var offset = 0; offset <= text.length; offset++) { | |
// draw text | |
textPainter.paint(canvas, Offset(0, dy)); | |
// draw cursor | |
var caretOffset = textPainter.getOffsetForCaret( | |
TextPosition(offset: offset, affinity: TextAffinity.upstream), | |
Rect.zero, | |
); | |
final dx = caretOffset.dx; | |
final rect = Rect.fromLTRB(dx, dy, dx + 3, dy + textPainter.height); | |
canvas.drawRect(rect, cursorPaint); | |
dy += textPainter.height; | |
} | |
} | |
@override | |
bool shouldRepaint(CustomPainter old) { | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment