-
-
Save pulyaevskiy/d7af7217c2e71f31dfb78699f91dfbb5 to your computer and use it in GitHub Desktop.
import 'package:flutter/widgets.dart'; | |
class Annotation extends Comparable<Annotation> { | |
Annotation({@required this.range, this.style}); | |
final TextRange range; | |
final TextStyle style; | |
@override | |
int compareTo(Annotation other) { | |
return range.start.compareTo(other.range.start); | |
} | |
@override | |
String toString() { | |
return 'Annotation(range:$range, style:$style)'; | |
} | |
} | |
class AnnotatedEditableText extends EditableText { | |
AnnotatedEditableText({ | |
Key key, | |
FocusNode focusNode, | |
TextEditingController controller, | |
TextStyle style, | |
ValueChanged<String> onChanged, | |
ValueChanged<String> onSubmitted, | |
Color cursorColor, | |
Color selectionColor, | |
TextSelectionControls selectionControls, | |
this.annotations, | |
}) : super( | |
key: key, | |
focusNode: focusNode, | |
controller: controller, | |
cursorColor: cursorColor, | |
style: style, | |
keyboardType: TextInputType.text, | |
autocorrect: true, | |
autofocus: true, | |
selectionColor: selectionColor, | |
selectionControls: selectionControls, | |
onChanged: onChanged, | |
onSubmitted: onSubmitted, | |
); | |
final List<Annotation> annotations; | |
@override | |
AnnotatedEditableTextState createState() => new AnnotatedEditableTextState(); | |
} | |
class AnnotatedEditableTextState extends EditableTextState { | |
@override | |
AnnotatedEditableText get widget => super.widget; | |
List<Annotation> getRanges() { | |
var source = widget.annotations; | |
source.sort(); | |
var result = new List<Annotation>(); | |
Annotation prev; | |
for (var item in source) { | |
if (prev == null) { | |
// First item, check if we need one before it. | |
if (item.range.start > 0) { | |
result.add(new Annotation( | |
range: TextRange(start: 0, end: item.range.start), | |
)); | |
} | |
result.add(item); | |
prev = item; | |
continue; | |
} else { | |
// Consequent item, check if there is a gap between. | |
if (prev.range.end > item.range.start) { | |
// Invalid ranges | |
throw new StateError( | |
'Invalid (intersecting) ranges for annotated field'); | |
} else if (prev.range.end < item.range.start) { | |
result.add(Annotation( | |
range: TextRange(start: prev.range.end, end: item.range.start), | |
)); | |
} | |
// Also add current annotation | |
result.add(item); | |
prev = item; | |
} | |
} | |
// Also check for trailing range | |
final String text = textEditingValue.text; | |
if (result.last.range.end < text.length) { | |
result.add(Annotation( | |
range: TextRange(start: result.last.range.end, end: text.length), | |
)); | |
} | |
return result; | |
} | |
@override | |
TextSpan buildTextSpan() { | |
final String text = textEditingValue.text; | |
if (widget.annotations != null) { | |
var items = getRanges(); | |
var children = <TextSpan>[]; | |
for (var item in items) { | |
children.add( | |
TextSpan(style: item.style, text: item.range.textInside(text)), | |
); | |
} | |
return new TextSpan(style: widget.style, children: children); | |
} | |
return new TextSpan(style: widget.style, text: text); | |
} | |
} |
When i try to write in it it gives me :
════════ Exception caught by widgets library ═══════════════════════════════════
The following StateError was thrown building Scrollable(axisDirection: right, physics: null, restorationId: null, dirty, dependencies: [ScrollConfiguration, _InheritedTheme, _LocalizationsScope-[GlobalKey#71eea], _EffectiveTickerMode, UnmanagedRestorationScope, MediaQuery], state: ScrollableState#af8e0(position: ScrollPositionWithSingleContext#d5829(offset: 0.0, range: 0.0..0.0, viewport: 200.0, ScrollableState, ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#a96de, ScrollDirection.idle), effective physics: ClampingScrollPhysics -> RangeMaintainingScrollPhysics)):
Bad state: No element
i run on chrome and i am on beta channel
EDIT: oups my fault, you need to refresh the annotions list at all changes, even if the list is empty or you don't use any for the moment
It is not supporting multiline , btw I am working on it ..to resolve this issue
You simply have to correct the buildTextSpan part. The error was raised when you delete a character because the Range could raise an exception. Here is my version that may fix your problem: