Improve ellipsizeMode prop

Summary:
There are a couple of buggy behaviors in the current implementation of the `ellipsizeMode` prop on Android:
  - Setting the `numberOfLines` prop stomps on whatever value you provided for `ellipsizeMode` earlier.
  - The value you've provided for `ellipsizeMode` is used even if you've configured your view to have an unlimited size (i.e. `numberOfLines` is 0 or unspecified).

This change fixes these issues which makes Android's `ellipsizeMode` prop more consistent with iOS's. Additionally, it renames LineBreakMode to EllipsizeMode in a couple of places.

**Test plan (required)**

Verified that the `numberOfLines` and `ellipsizeMode` props work correctly in an Android test app.

Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/9594

Differential Revision: D3810166

Pulled By: foghina

fbshipit-source-id: 229c9bfc3ef10670a1090311ea9d095cb2c1121a
This commit is contained in:
Adam Comella 2016-09-02 00:45:28 -07:00 committed by Facebook Github Bot
parent d8abea1bf7
commit cd1a86db36
3 changed files with 37 additions and 15 deletions

View File

@ -75,7 +75,7 @@ public class ViewProps {
public static final String LINE_HEIGHT = "lineHeight";
public static final String NEEDS_OFFSCREEN_ALPHA_COMPOSITING = "needsOffscreenAlphaCompositing";
public static final String NUMBER_OF_LINES = "numberOfLines";
public static final String LINE_BREAK_MODE = "ellipsizeMode";
public static final String ELLIPSIZE_MODE = "ellipsizeMode";
public static final String ON = "on";
public static final String RESIZE_MODE = "resizeMode";
public static final String TEXT_ALIGN = "textAlign";

View File

@ -13,12 +13,16 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.TextView;
import com.facebook.csslayout.FloatUtil;
import com.facebook.react.uimanager.ReactCompoundView;
import com.facebook.react.uimanager.ViewDefaults;
import javax.annotation.Nullable;
public class ReactTextView extends TextView implements ReactCompoundView {
@ -31,6 +35,8 @@ public class ReactTextView extends TextView implements ReactCompoundView {
private boolean mTextIsSelectable;
private float mLineHeight = Float.NaN;
private int mTextAlign = Gravity.NO_GRAVITY;
private int mNumberOfLines = ViewDefaults.NUMBER_OF_LINES;
private TextUtils.TruncateAt mEllipsizeLocation = TextUtils.TruncateAt.END;
public ReactTextView(Context context) {
super(context);
@ -213,4 +219,18 @@ public class ReactTextView extends TextView implements ReactCompoundView {
}
setGravity((getGravity() & ~Gravity.VERTICAL_GRAVITY_MASK) | gravityVertical);
}
public void setNumberOfLines(int numberOfLines) {
mNumberOfLines = numberOfLines == 0 ? ViewDefaults.NUMBER_OF_LINES : numberOfLines;
setMaxLines(mNumberOfLines);
}
public void setEllipsizeLocation(TextUtils.TruncateAt ellipsizeLocation) {
mEllipsizeLocation = ellipsizeLocation;
}
public void updateView() {
@Nullable TextUtils.TruncateAt ellipsizeLocation = mNumberOfLines == ViewDefaults.NUMBER_OF_LINES ? null : mEllipsizeLocation;
setEllipsize(ellipsizeLocation);
}
}

View File

@ -18,7 +18,6 @@ import android.widget.TextView;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewDefaults;
@ -51,22 +50,19 @@ public class ReactTextViewManager extends BaseViewManager<ReactTextView, ReactTe
// maxLines can only be set in master view (block), doesn't really make sense to set in a span
@ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = ViewDefaults.NUMBER_OF_LINES)
public void setNumberOfLines(ReactTextView view, int numberOfLines) {
view.setMaxLines(numberOfLines == 0 ? ViewDefaults.NUMBER_OF_LINES : numberOfLines);
view.setEllipsize(TextUtils.TruncateAt.END);
view.setNumberOfLines(numberOfLines);
}
@ReactProp(name = ViewProps.LINE_BREAK_MODE)
public void setLineBreakMode(ReactTextView view, @Nullable String ellipsizeMode) {
if(ellipsizeMode == null) {
return;
}
if (ellipsizeMode.equals("head")) {
view.setEllipsize(TextUtils.TruncateAt.START);
@ReactProp(name = ViewProps.ELLIPSIZE_MODE)
public void setEllipsizeMode(ReactTextView view, @Nullable String ellipsizeMode) {
if (ellipsizeMode == null || ellipsizeMode.equals("tail")) {
view.setEllipsizeLocation(TextUtils.TruncateAt.END);
} else if (ellipsizeMode.equals("head")) {
view.setEllipsizeLocation(TextUtils.TruncateAt.START);
} else if (ellipsizeMode.equals("middle")) {
view.setEllipsize(TextUtils.TruncateAt.MIDDLE);
} else if (ellipsizeMode.equals("tail")) {
view.setEllipsize(TextUtils.TruncateAt.END);
view.setEllipsizeLocation(TextUtils.TruncateAt.MIDDLE);
} else {
throw new JSApplicationIllegalArgumentException("Invalid ellipsizeMode: " + ellipsizeMode);
}
}
@ -109,4 +105,10 @@ public class ReactTextViewManager extends BaseViewManager<ReactTextView, ReactTe
public Class<ReactTextShadowNode> getShadowNodeClass() {
return ReactTextShadowNode.class;
}
@Override
protected void onAfterUpdateTransaction(ReactTextView view) {
super.onAfterUpdateTransaction(view);
view.updateView();
}
}