You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.6 KiB
Dart
122 lines
3.6 KiB
Dart
import 'dart:math';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:tangheem/classes/colors.dart';
|
|
|
|
class TextHighLightWidget extends StatelessWidget {
|
|
final String text;
|
|
final String valueText;
|
|
final Color valueColor;
|
|
final List<String> highlights;
|
|
final TextStyle style;
|
|
final TextAlign textAlign;
|
|
final Color highLightColor = ColorConsts.secondaryOrange;
|
|
final Function(String) onTap;
|
|
|
|
TextHighLightWidget({Key key, this.text, this.textAlign = TextAlign.center, this.valueText, this.valueColor, this.highlights, this.style = const TextStyle(), this.onTap});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (text == '') {
|
|
return _richText(_normalSpan(text));
|
|
}
|
|
if (highlights.isEmpty) {
|
|
return _richText(_normalSpan(text));
|
|
}
|
|
for (int i = 0; i < highlights.length; i++) {
|
|
if (highlights[i] == null) {
|
|
assert(highlights[i] != null);
|
|
return _richText(_normalSpan(text));
|
|
}
|
|
if (highlights[i].isEmpty) {
|
|
assert(highlights[i].isNotEmpty);
|
|
return _richText(_normalSpan(text));
|
|
}
|
|
}
|
|
|
|
List<TextSpan> _spans = List();
|
|
int _start = 0;
|
|
List<String> _lowerCaseHighlights = List();
|
|
|
|
highlights.forEach((element) {
|
|
_lowerCaseHighlights.add(element.toLowerCase());
|
|
});
|
|
|
|
while (true) {
|
|
Map<int, String> _highlightsMap = Map();
|
|
|
|
for (int i = 0; i < highlights.length; i++) {
|
|
int _index = text.toLowerCase().indexOf(_lowerCaseHighlights[i], _start);
|
|
if (_index >= 0) {
|
|
_highlightsMap.putIfAbsent(_index, () => highlights[i]);
|
|
}
|
|
}
|
|
|
|
if (_highlightsMap.isNotEmpty) {
|
|
List<int> _indexes = List();
|
|
_highlightsMap.forEach((key, value) => _indexes.add(key));
|
|
|
|
int _currentIndex = _indexes.reduce(min);
|
|
String _currentHighlight = text.substring(_currentIndex, _currentIndex + _highlightsMap[_currentIndex].length);
|
|
|
|
if (_currentIndex == _start) {
|
|
_spans.add(_highlightSpan(_currentHighlight));
|
|
_start += _currentHighlight.length;
|
|
} else {
|
|
_spans.add(_normalSpan(text.substring(_start, _currentIndex)));
|
|
_spans.add(_highlightSpan(_currentHighlight));
|
|
_start = _currentIndex + _currentHighlight.length;
|
|
}
|
|
} else {
|
|
_spans.add(_normalSpan(text.substring(_start, text.length)));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (valueText != null) {
|
|
_spans.add(TextSpan(
|
|
text: ' ' + valueText,
|
|
style: TextStyle(color: valueColor ?? Color(0xff170026), fontSize: 12, fontWeight: FontWeight.w800),
|
|
));
|
|
}
|
|
return _richText(TextSpan(children: _spans));
|
|
}
|
|
|
|
TextSpan _highlightSpan(String value) {
|
|
if (style.color == null) {
|
|
return TextSpan(
|
|
text: value,
|
|
style: style.copyWith(color: highLightColor, fontSize: 18),
|
|
recognizer: TapGestureRecognizer()
|
|
..onTap = () {
|
|
if (onTap != null) {
|
|
onTap(value);
|
|
}
|
|
});
|
|
} else {
|
|
return TextSpan(text: value, style: style.copyWith(color: valueColor));
|
|
}
|
|
}
|
|
|
|
TextSpan _normalSpan(String value) {
|
|
if (style.color == null) {
|
|
return TextSpan(
|
|
text: value,
|
|
style: style.copyWith(color: valueColor),
|
|
);
|
|
} else {
|
|
return TextSpan(text: value, style: style, children: [
|
|
if (valueText != null)
|
|
TextSpan(
|
|
text: ' ' + valueText,
|
|
style: style,
|
|
)
|
|
]);
|
|
}
|
|
}
|
|
|
|
RichText _richText(TextSpan text) {
|
|
return RichText(key: key, text: text, textAlign: textAlign);
|
|
}
|
|
}
|