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 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 _spans = List(); int _start = 0; List _lowerCaseHighlights = List(); highlights.forEach((element) { _lowerCaseHighlights.add(element.toLowerCase()); }); while (true) { Map _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 _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); } }