Created
June 28, 2018 19:39
-
-
Save pulyaevskiy/d7af7217c2e71f31dfb78699f91dfbb5 to your computer and use it in GitHub Desktop.
AnnotatedEditableText
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/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); | |
} | |
} |
It is not supporting multiline , btw I am working on it ..to resolve this issue
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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