mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement FabricViewStateManager for ReactEditText
Summary: Implement FabricViewStateManager for ReactEditText. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D22941069 fbshipit-source-id: 44651d1a3500e4dcd36f94f339cb25ea25b1f3f9
This commit is contained in:
committed by
Facebook GitHub Bot
parent
33bccbe2ec
commit
065fbe3be5
@@ -39,7 +39,7 @@ import androidx.core.view.ViewCompat;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.JavaOnlyMap;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.FabricViewStateManager;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.views.text.ReactSpan;
|
||||
import com.facebook.react.views.text.ReactTextUpdate;
|
||||
@@ -61,7 +61,8 @@ import java.util.ArrayList;
|
||||
* called this explicitly. This is the default behavior on other platforms as well.
|
||||
* VisibleForTesting from {@link TextInputEventsTestCase}.
|
||||
*/
|
||||
public class ReactEditText extends AppCompatEditText {
|
||||
public class ReactEditText extends AppCompatEditText
|
||||
implements FabricViewStateManager.HasFabricViewStateManager {
|
||||
|
||||
private final InputMethodManager mInputMethodManager;
|
||||
// This flag is set to true when we set the text of the EditText explicitly. In that case, no
|
||||
@@ -100,7 +101,7 @@ public class ReactEditText extends AppCompatEditText {
|
||||
private ReactViewBackgroundManager mReactBackgroundManager;
|
||||
|
||||
protected @Nullable JavaOnlyMap mAttributedString = null;
|
||||
protected @Nullable StateWrapper mStateWrapper = null;
|
||||
private final FabricViewStateManager mFabricViewStateManager = new FabricViewStateManager();
|
||||
protected boolean mDisableTextDiffing = false;
|
||||
|
||||
protected boolean mIsSettingTextFromState = false;
|
||||
@@ -605,7 +606,7 @@ public class ReactEditText extends AppCompatEditText {
|
||||
// wrapper 100% of the time.
|
||||
// Since the LocalData object is constructed by getting values from the underlying EditText
|
||||
// view, we don't need to construct one or apply it at all - it provides no use in Fabric.
|
||||
if (mStateWrapper == null) {
|
||||
if (!mFabricViewStateManager.hasStateWrapper()) {
|
||||
ReactContext reactContext = getReactContext(this);
|
||||
final ReactTextInputLocalData localData = new ReactTextInputLocalData(this);
|
||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
||||
@@ -820,6 +821,11 @@ public class ReactEditText extends AppCompatEditText {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricViewStateManager getFabricViewStateManager() {
|
||||
return mFabricViewStateManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class will redirect *TextChanged calls to the listeners only in the case where the text is
|
||||
* changed by the user, and not explicitly set by JS.
|
||||
|
||||
+30
-19
@@ -50,6 +50,7 @@ import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.BaseViewManager;
|
||||
import com.facebook.react.uimanager.FabricViewStateManager;
|
||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
@@ -919,7 +920,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
}
|
||||
|
||||
// Fabric: update representation of AttributedString
|
||||
JavaOnlyMap attributedString = mEditText.mAttributedString;
|
||||
final JavaOnlyMap attributedString = mEditText.mAttributedString;
|
||||
if (attributedString != null && attributedString.hasKey("fragments")) {
|
||||
String changedText = s.subSequence(start, start + count).toString();
|
||||
|
||||
@@ -981,27 +982,35 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
// we must recreate these data structures every time. It would be nice to have a
|
||||
// reusable data-structure to use for TextInput because constructing these and copying
|
||||
// on every keystroke is very expensive.
|
||||
if (mEditText.mStateWrapper != null && attributedString != null) {
|
||||
WritableMap map = new WritableNativeMap();
|
||||
WritableMap newAttributedString = new WritableNativeMap();
|
||||
if (mEditText.getFabricViewStateManager().hasStateWrapper() && attributedString != null) {
|
||||
mEditText
|
||||
.getFabricViewStateManager()
|
||||
.setState(
|
||||
new FabricViewStateManager.StateUpdateCallback() {
|
||||
@Override
|
||||
public WritableMap getStateUpdate() {
|
||||
WritableMap map = new WritableNativeMap();
|
||||
WritableMap newAttributedString = new WritableNativeMap();
|
||||
|
||||
WritableArray fragments = new WritableNativeArray();
|
||||
WritableArray fragments = new WritableNativeArray();
|
||||
|
||||
for (int i = 0; i < attributedString.getArray("fragments").size(); i++) {
|
||||
ReadableMap readableFragment = attributedString.getArray("fragments").getMap(i);
|
||||
WritableMap fragment = new WritableNativeMap();
|
||||
fragment.putDouble("reactTag", readableFragment.getInt("reactTag"));
|
||||
fragment.putString("string", readableFragment.getString("string"));
|
||||
fragments.pushMap(fragment);
|
||||
}
|
||||
for (int i = 0; i < attributedString.getArray("fragments").size(); i++) {
|
||||
ReadableMap readableFragment =
|
||||
attributedString.getArray("fragments").getMap(i);
|
||||
WritableMap fragment = new WritableNativeMap();
|
||||
fragment.putDouble("reactTag", readableFragment.getInt("reactTag"));
|
||||
fragment.putString("string", readableFragment.getString("string"));
|
||||
fragments.pushMap(fragment);
|
||||
}
|
||||
|
||||
newAttributedString.putString("string", attributedString.getString("string"));
|
||||
newAttributedString.putArray("fragments", fragments);
|
||||
newAttributedString.putString("string", attributedString.getString("string"));
|
||||
newAttributedString.putArray("fragments", fragments);
|
||||
|
||||
map.putInt("mostRecentEventCount", mEditText.incrementAndGetEventCounter());
|
||||
map.putMap("textChanged", newAttributedString);
|
||||
|
||||
mEditText.mStateWrapper.updateState(map);
|
||||
map.putInt("mostRecentEventCount", mEditText.incrementAndGetEventCounter());
|
||||
map.putMap("textChanged", newAttributedString);
|
||||
return map;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// The event that contains the event counter and updates it must be sent first.
|
||||
@@ -1235,6 +1244,9 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
@Override
|
||||
public Object updateState(
|
||||
ReactEditText view, ReactStylesDiffMap props, @Nullable StateWrapper stateWrapper) {
|
||||
|
||||
view.getFabricViewStateManager().setStateWrapper(stateWrapper);
|
||||
|
||||
if (stateWrapper == null) {
|
||||
throw new IllegalArgumentException("Unable to update a NULL state.");
|
||||
}
|
||||
@@ -1254,7 +1266,6 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
int textBreakStrategy =
|
||||
TextAttributeProps.getTextBreakStrategy(paragraphAttributes.getString("textBreakStrategy"));
|
||||
|
||||
view.mStateWrapper = stateWrapper;
|
||||
return ReactTextUpdate.buildReactTextUpdateFromState(
|
||||
spanned,
|
||||
state.getInt("mostRecentEventCount"),
|
||||
|
||||
Reference in New Issue
Block a user