I want to make an Epub Reader with text highlighting, text selections. But I tried using RichText and highlight_text package. But it is static and does not add highlighting animations. Like I want to show the highlight happening (brush stroke from right to left on a word). In Flutter, is there any way to do it? I want to add animations to each text highlight:
`TextHighlight(
//This widget uses RichText and nested TextSpan for highlighting
//I want to add animations to the text Inside TextSpan
text: text,
words: words as LinkedHashMap<String, HighlightedWord>,
textStyle: TextStyle(
fontSize: 20.0,
color: Colors.black,
backgroundColor: Colors.transparent,
),`
Flutter package I am using highlight_text ``
library highlight_text;
import 'dart:collection';
import 'dart:core';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class HighlightedWord {
final TextStyle textStyle;
final VoidCallback onTap;
HighlightedWord({
required this.onTap,
required this.textStyle,
});
}
class TextHighlight extends StatefulWidget {
String text;
TextAlign textAlign;
TextDirection? textDirection;
bool softWrap;
TextOverflow overflow;
double textScaleFactor;
int? maxLines;
Locale? locale;
StrutStyle? strutStyle;
bool enableCaseSensitive;
TextHighlight({
required this.text,
required this.words,
this.textStyle = const TextStyle(
fontSize: 25.0,
color: Colors.black,
),
this.textAlign = TextAlign.start,
this.textDirection,
this.softWrap = true,
this.overflow = TextOverflow.clip,
this.textScaleFactor = 1.0,
this.maxLines,
this.locale,
this.strutStyle,
this.enableCaseSensitive = false,
});
@override
_TextHightlightState createState() => _TextHighlightState(
required this.text,
required this.words,
this.textStyle = const TextStyle(
fontSize: 25.0,
color: Colors.black,
),
this.textAlign = TextAlign.start,
this.textDirection,
this.softWrap = true,
this.overflow = TextOverflow.clip,
this.textScaleFactor = 1.0,
this.maxLines,
this.locale,
this.strutStyle,
this.enableCaseSensitive = false,
);
}
class _TextHighlightState extends State<TextHighlight> {
String text;
TextAlign textAlign;
TextDirection? textDirection;
bool softWrap;
TextOverflow overflow;
double textScaleFactor;
int? maxLines;
Locale? locale;
StrutStyle? strutStyle;
bool enableCaseSensitive;
@override
void initState(){
text = widget.text;
textAlign = widget.textAlign;
super.initState();
}
@override
Widget build(BuildContext context) {
List<String> _textWords = _bind();
return AnimatedDefaultTextStyle(
child: RichText(
text: _buildSpan(_textWords),
locale: locale,
maxLines: maxLines,
overflow: overflow,
softWrap: softWrap,
strutStyle: strutStyle,
textAlign: textAlign,
textDirection: textDirection,
textScaleFactor: textScaleFactor,
),
);
}
List<String> _bind() {
String bindedText = text;
for (String word in words.keys) {
if (enableCaseSensitive) {
bindedText = bindedText.replaceAll(
word, '<highlight>${words.keys.toList().indexOf(word)}<highlight>');
} else {
int strIndex = bindedText.toLowerCase().indexOf(word.toLowerCase());
print('$word\n');
bindedText = bindedText.replaceRange(strIndex, strIndex + word.length,
'<highlight>${words.keys.toList().indexOf(word)}<highlight>');
}
}
List<String> splitedTexts = bindedText.split("<highlight>");
splitedTexts.removeWhere((s) => s.isEmpty);
return splitedTexts;
}
TextSpan _buildSpan(List<String> bindedWords) {
if (bindedWords.isEmpty) return TextSpan();
String nextToDisplay = bindedWords.first;
bindedWords.removeAt(0);
int? index = int.tryParse(nextToDisplay);
if (index != null) {
String currentWord = words.keys.toList()[index];
return TextSpan(
text: currentWord,
style: words[currentWord]!.textStyle,
children: [
_buildSpan(bindedWords),
],
recognizer: TapGestureRecognizer()
..onTap = () => words[currentWord]!.onTap(),
);
}
return TextSpan(
text: nextToDisplay,
style: textStyle,
children: [
_buildSpan(bindedWords),
],
);
}
}
Is there any way to do animations, tweaking the package code in some way.. or any other workaround.. Baiscally I want to highlight a specific text, rendered by Text widget. In mobile and Web.