mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
ReactTextView View recycling
Summary: See previous diff for details on general approach and benchmarks. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D36676887 fbshipit-source-id: b177dcd19f1ea687bf7d2d4f2f637d2924723340
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7b778fbebb
commit
b1701bd20f
@@ -100,6 +100,8 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
||||
view.setRight(0);
|
||||
view.setElevation(0);
|
||||
view.setAnimationMatrix(null);
|
||||
|
||||
// setShadowColor
|
||||
view.setOutlineAmbientShadowColor(Color.BLACK);
|
||||
view.setOutlineSpotShadowColor(Color.BLACK);
|
||||
|
||||
|
||||
+18
-17
@@ -193,24 +193,25 @@ public abstract class ReactTextAnchorViewManager<T extends View, C extends React
|
||||
|
||||
@ReactProp(name = "dataDetectorType")
|
||||
public void setDataDetectorType(ReactTextView view, @Nullable String type) {
|
||||
switch (type) {
|
||||
case "phoneNumber":
|
||||
view.setLinkifyMask(Linkify.PHONE_NUMBERS);
|
||||
break;
|
||||
case "link":
|
||||
view.setLinkifyMask(Linkify.WEB_URLS);
|
||||
break;
|
||||
case "email":
|
||||
view.setLinkifyMask(Linkify.EMAIL_ADDRESSES);
|
||||
break;
|
||||
case "all":
|
||||
view.setLinkifyMask(Linkify.ALL);
|
||||
break;
|
||||
case "none":
|
||||
default:
|
||||
view.setLinkifyMask(0);
|
||||
break;
|
||||
if (type != null) {
|
||||
switch (type) {
|
||||
case "phoneNumber":
|
||||
view.setLinkifyMask(Linkify.PHONE_NUMBERS);
|
||||
return;
|
||||
case "link":
|
||||
view.setLinkifyMask(Linkify.WEB_URLS);
|
||||
return;
|
||||
case "email":
|
||||
view.setLinkifyMask(Linkify.EMAIL_ADDRESSES);
|
||||
return;
|
||||
case "all":
|
||||
view.setLinkifyMask(Linkify.ALL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// "none" case, default, and null type are equivalent.
|
||||
view.setLinkifyMask(0);
|
||||
}
|
||||
|
||||
@ReactProp(name = "onInlineViewLayout")
|
||||
|
||||
@@ -54,23 +54,102 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
||||
private boolean mContainsImages;
|
||||
private int mDefaultGravityHorizontal;
|
||||
private int mDefaultGravityVertical;
|
||||
private int mTextAlign = Gravity.NO_GRAVITY;
|
||||
private int mNumberOfLines = ViewDefaults.NUMBER_OF_LINES;
|
||||
private TextUtils.TruncateAt mEllipsizeLocation = TextUtils.TruncateAt.END;
|
||||
private boolean mAdjustsFontSizeToFit = false;
|
||||
private int mLinkifyMaskType = 0;
|
||||
private int mTextAlign;
|
||||
private int mNumberOfLines;
|
||||
private TextUtils.TruncateAt mEllipsizeLocation;
|
||||
private boolean mAdjustsFontSizeToFit;
|
||||
private int mLinkifyMaskType;
|
||||
private boolean mNotifyOnInlineViewLayout;
|
||||
private boolean mTextIsSelectable = false;
|
||||
private boolean mTextIsSelectable;
|
||||
|
||||
private ReactViewBackgroundManager mReactBackgroundManager;
|
||||
private Spannable mSpanned;
|
||||
|
||||
public ReactTextView(Context context) {
|
||||
super(context);
|
||||
initView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all default values here as opposed to in the constructor or field defaults. It is important
|
||||
* that these properties are set during the constructor, but also on-demand whenever an existing
|
||||
* ReactTextView is recycled.
|
||||
*/
|
||||
private void initView() {
|
||||
if (mReactBackgroundManager != null) {
|
||||
// make sure old background manager doesn't have any references back to this View
|
||||
mReactBackgroundManager.cleanup();
|
||||
}
|
||||
|
||||
mReactBackgroundManager = new ReactViewBackgroundManager(this);
|
||||
mDefaultGravityHorizontal =
|
||||
getGravity() & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
|
||||
mDefaultGravityVertical = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
|
||||
|
||||
mTextAlign = Gravity.NO_GRAVITY;
|
||||
mNumberOfLines = ViewDefaults.NUMBER_OF_LINES;
|
||||
mAdjustsFontSizeToFit = false;
|
||||
mLinkifyMaskType = 0;
|
||||
mTextIsSelectable = false;
|
||||
mEllipsizeLocation = TextUtils.TruncateAt.END;
|
||||
|
||||
mSpanned = null;
|
||||
}
|
||||
|
||||
/* package */ void recycleView(ReactTextView defaultView) {
|
||||
// Set default field values
|
||||
initView();
|
||||
|
||||
setForeground(null);
|
||||
|
||||
// reset text
|
||||
setLayoutParams(EMPTY_LAYOUT_PARAMS);
|
||||
setMovementMethod(defaultView.getMovementMethod());
|
||||
setBreakStrategy(defaultView.getBreakStrategy());
|
||||
super.setText(null);
|
||||
|
||||
// Call setters to ensure that any super setters are called
|
||||
setGravityHorizontal(mDefaultGravityHorizontal);
|
||||
setGravityVertical(mDefaultGravityVertical);
|
||||
setNumberOfLines(mNumberOfLines);
|
||||
setAdjustFontSizeToFit(mAdjustsFontSizeToFit);
|
||||
setLinkifyMask(mLinkifyMaskType);
|
||||
setTextIsSelectable(mTextIsSelectable);
|
||||
|
||||
// Default true:
|
||||
// https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/widget/TextView.java#L9347
|
||||
setIncludeFontPadding(true);
|
||||
setEnabled(true);
|
||||
|
||||
// reset data detectors
|
||||
setLinkifyMask(0);
|
||||
|
||||
setJustificationMode(defaultView.getJustificationMode());
|
||||
|
||||
setEllipsizeLocation(mEllipsizeLocation);
|
||||
|
||||
// Focus IDs
|
||||
// Also see in AOSP source:
|
||||
// https://android.googlesource.com/platform/frameworks/base/+/a175a5b/core/java/android/view/View.java#4493
|
||||
setNextFocusDownId(View.NO_ID);
|
||||
setNextFocusForwardId(View.NO_ID);
|
||||
setNextFocusRightId(View.NO_ID);
|
||||
setNextFocusUpId(View.NO_ID);
|
||||
|
||||
// https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-mainline-12.0.0_r96/core/java/android/view/View.java#5491
|
||||
setElevation(0);
|
||||
|
||||
// View flags - defaults are here:
|
||||
// https://android.googlesource.com/platform/frameworks/base/+/98e54bb941cb6feb07127b75da37833281951d52/core/java/android/view/View.java#5311
|
||||
// mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED |
|
||||
// LAYOUT_DIRECTION_INHERIT;
|
||||
setEnabled(true);
|
||||
setFocusable(View.FOCUSABLE_AUTO);
|
||||
|
||||
// Things that could be set as a result of updateText/setText
|
||||
setPadding(0, 0, 0, 0);
|
||||
|
||||
updateView(); // call after changing ellipsizeLocation in particular
|
||||
}
|
||||
|
||||
private static WritableMap inlineViewJson(
|
||||
|
||||
@@ -9,6 +9,7 @@ package com.facebook.react.views.text;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Spannable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.R;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
@@ -44,8 +45,37 @@ public class ReactTextViewManager
|
||||
|
||||
@VisibleForTesting public static final String REACT_CLASS = "RCTText";
|
||||
|
||||
private ReactTextView mDefaultViewForRecycling = null;
|
||||
|
||||
protected @Nullable ReactTextViewManagerCallback mReactTextViewManagerCallback;
|
||||
|
||||
public ReactTextViewManager() {
|
||||
super();
|
||||
|
||||
enableViewRecycling();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactTextView prepareToRecycleView(
|
||||
@NonNull ThemedReactContext reactContext, ReactTextView view) {
|
||||
// TODO: use context as key
|
||||
if (mDefaultViewForRecycling == null) {
|
||||
mDefaultViewForRecycling = createViewInstance(reactContext);
|
||||
}
|
||||
|
||||
// BaseViewManager
|
||||
super.prepareToRecycleView(reactContext, view);
|
||||
|
||||
// Resets background and borders
|
||||
view.recycleView(mDefaultViewForRecycling);
|
||||
|
||||
// Defaults from ReactTextAnchorViewManager
|
||||
setSelectionColor(view, null);
|
||||
setAndroidHyphenationFrequency(view, null);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return REACT_CLASS;
|
||||
|
||||
Reference in New Issue
Block a user