RCTVirtualText wasn't clickable in certain cases

Summary:
Text in Nodes is squashed into a single DrawCommand for drawing a
Boring or StaticLayout. Touch is handled using a TextNodeRegion subclass of
NodeRegion that knows how to identify pieces of text inside of the DrawCommand
based on spans in the text. However, we only use a TextNodeRegion on the
second call for updateNodeRegion for an RCTText. If there is only one call,
the NodeRegion will just be a normal one. This patch ensures that the
NodeRegion for an RCTText is always a TextNodeRegion, allowing for null
Layouts that are set when the DrawCommand is made.

Reviewed By: astreet

Differential Revision: D3291682
This commit is contained in:
Ahmed El-Helw
2016-05-16 12:35:08 -07:00
parent 9d67989001
commit c62840c7a8
2 changed files with 36 additions and 15 deletions
@@ -9,11 +9,13 @@
package com.facebook.react.flat;
import javax.annotation.Nullable;
import android.text.Layout;
import android.text.Spanned;
/* package */ final class TextNodeRegion extends NodeRegion {
private final Layout mLayout;
private @Nullable Layout mLayout;
/* package */ TextNodeRegion(
float left,
@@ -22,29 +24,35 @@ import android.text.Spanned;
float bottom,
int tag,
boolean isVirtual,
Layout layout) {
@Nullable Layout layout) {
super(left, top, right, bottom, tag, isVirtual);
mLayout = layout;
}
/* package */ Layout getLayout() {
public void setLayout(Layout layout) {
mLayout = layout;
}
/* package */ @Nullable Layout getLayout() {
return mLayout;
}
/* package */ int getReactTag(float touchX, float touchY) {
int y = Math.round(touchY - mTop);
if (y >= mLayout.getLineTop(0) && y < mLayout.getLineBottom(mLayout.getLineCount() - 1)) {
float x = Math.round(touchX - mLeft);
int line = mLayout.getLineForVertical(y);
if (mLayout != null) {
int y = Math.round(touchY - mTop);
if (y >= mLayout.getLineTop(0) && y < mLayout.getLineBottom(mLayout.getLineCount() - 1)) {
float x = Math.round(touchX - mLeft);
int line = mLayout.getLineForVertical(y);
if (mLayout.getLineLeft(line) <= x && x <= mLayout.getLineRight(line)) {
int off = mLayout.getOffsetForHorizontal(line, x);
if (mLayout.getLineLeft(line) <= x && x <= mLayout.getLineRight(line)) {
int off = mLayout.getOffsetForHorizontal(line, x);
Spanned text = (Spanned) mLayout.getText();
RCTRawText[] link = text.getSpans(off, off, RCTRawText.class);
Spanned text = (Spanned) mLayout.getText();
RCTRawText[] link = text.getSpans(off, off, RCTRawText.class);
if (link.length != 0) {
return link[0].getReactTag();
if (link.length != 0) {
return link[0].getReactTag();
}
}
}
}