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:
parent
d8abea1bf7
commit
cd1a86db36
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue