diff --git a/Examples/UIExplorer/TextInputExample.android.js b/Examples/UIExplorer/TextInputExample.android.js
index b70f2d933..5ae1079f0 100644
--- a/Examples/UIExplorer/TextInputExample.android.js
+++ b/Examples/UIExplorer/TextInputExample.android.js
@@ -91,6 +91,60 @@ class RewriteExample extends React.Component {
}
}
+class TokenizedTextExample extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {text: 'Hello #World'};
+ }
+ render() {
+
+ //define delimiter
+ let delimiter = /\s+/;
+
+ //split string
+ let _text = this.state.text;
+ let token, index, parts = [];
+ while (_text) {
+ delimiter.lastIndex = 0;
+ token = delimiter.exec(_text);
+ if (token === null) {
+ break;
+ }
+ index = token.index;
+ if (token[0].length === 0) {
+ index = 1;
+ }
+ parts.push(_text.substr(0, index));
+ parts.push(token[0]);
+ index = index + token[0].length;
+ _text = _text.slice(index);
+ }
+ parts.push(_text);
+
+ //highlight hashtags
+ parts = parts.map((text) => {
+ if (/^#/.test(text)) {
+ return {text};
+ } else {
+ return text;
+ }
+ });
+
+ return (
+
+ {
+ this.setState({text});
+ }}>
+ {parts}
+
+
+ );
+ }
+}
+
var styles = StyleSheet.create({
multiline: {
height: 60,
@@ -109,6 +163,10 @@ var styles = StyleSheet.create({
singleLineWithHeightTextInput: {
height: 30,
},
+ hashtag: {
+ color: 'blue',
+ fontWeight: 'bold',
+ },
});
exports.title = '';
@@ -322,4 +380,10 @@ exports.examples = [
);
}
},
+ {
+ title: 'Attributed text',
+ render: function() {
+ return ;
+ }
+ },
];
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java
index 79a67f864..4c5f8011c 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java
@@ -20,12 +20,17 @@ import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextWatcher;
+import android.text.style.AbsoluteSizeSpan;
+import android.text.style.BackgroundColorSpan;
+import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import com.facebook.infer.annotation.Assertions;
+import com.facebook.react.views.text.CustomStyleSpan;
+import com.facebook.react.views.text.ReactTagSpan;
/**
* A wrapper around the EditText that lets us better control what happens when an EditText gets
@@ -204,6 +209,15 @@ public class ReactEditText extends EditText {
private void manageSpans(SpannableStringBuilder spannableStringBuilder) {
Object[] spans = getText().getSpans(0, length(), Object.class);
for (int spanIdx = 0; spanIdx < spans.length; spanIdx++) {
+ // Remove all styling spans we might have previously set
+ if (ForegroundColorSpan.class.isInstance(spans[spanIdx]) ||
+ BackgroundColorSpan.class.isInstance(spans[spanIdx]) ||
+ AbsoluteSizeSpan.class.isInstance(spans[spanIdx]) ||
+ CustomStyleSpan.class.isInstance(spans[spanIdx]) ||
+ ReactTagSpan.class.isInstance(spans[spanIdx])) {
+ getText().removeSpan(spans[spanIdx]);
+ }
+
if ((getText().getSpanFlags(spans[spanIdx]) & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) !=
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) {
continue;
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java
index f7363441b..268b5c465 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java
@@ -16,8 +16,9 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
/**
* Event emitted by EditText native view when text changes.
+ * VisibleForTesting from {@link TextInputEventsTestCase}.
*/
-/* package */ class ReactTextChangedEvent extends Event {
+public class ReactTextChangedEvent extends Event {
public static final String EVENT_NAME = "topChange";
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputEvent.java
index f2cbc8b91..3d8f4ccbb 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputEvent.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputEvent.java
@@ -16,8 +16,9 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
/**
* Event emitted by EditText native view when text changes.
+ * VisibleForTesting from {@link TextInputEventsTestCase}.
*/
-/* package */ class ReactTextInputEvent extends Event {
+public class ReactTextInputEvent extends Event {
public static final String EVENT_NAME = "topTextInput";