mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Support animating text color with native driver
Summary: Typically, ReactTextView#setText is called via ReactTextViewManager#updateExtraData, but natively animated color changes bypass render and layout pass via direct call to SurfaceMountingManager#updateProps from UIManager#synchronouslyUpdateViewOnUIThread. Thus, for animated color changes to get applied, we need to handle the color prop in ReactTextAnchorViewManager. In addition, native driver updates are not synchronized with Fabric's mounting; if the native driver update happens before mount, the update is done in updateState. Changelog: [Android][Added] - Support animating text color with native driver Reviewed By: mdvacca Differential Revision: D34630294 fbshipit-source-id: c0f1e19c801c0e909e84387d623a6556ce6f2d67
This commit is contained in:
committed by
Facebook GitHub Bot
parent
e1dc9a756b
commit
87cdb607e4
@@ -8,10 +8,12 @@
|
||||
package com.facebook.react.uimanager;
|
||||
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.Dynamic;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -85,11 +87,16 @@ public class ReactStylesDiffMap {
|
||||
return mBackingMap.getMap(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
public Dynamic getDynamic(String key) {
|
||||
return mBackingMap.getDynamic(key);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ReadableType getType(String key) {
|
||||
return mBackingMap.getType(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{ " + getClass().getSimpleName() + ": " + mBackingMap.toString() + " }";
|
||||
|
||||
+19
@@ -48,6 +48,25 @@ public abstract class ReactTextAnchorViewManager<T extends View, C extends React
|
||||
view.setFocusable(accessible);
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.COLOR, customType = "Color")
|
||||
public void setColor(ReactTextView view, int color) {
|
||||
/**
|
||||
* This is needed for natively driven animations for text color. Typically, {@link
|
||||
* ReactTextView#setText} is called via {@link ReactTextViewManager#updateExtraData}, but
|
||||
* natively animated color changes bypass render and layout pass via direct call to {@link
|
||||
* SurfaceMountingManager#updateProps} from {@link UIManager#synchronouslyUpdateViewOnUIThread}.
|
||||
*/
|
||||
Spannable spannable = view.getSpanned();
|
||||
if (spannable != null) {
|
||||
spannable.setSpan(
|
||||
new ReactForegroundColorSpan(color),
|
||||
0,
|
||||
spannable.length(),
|
||||
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
view.setText(spannable);
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import android.text.Spannable;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableNativeMap;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
|
||||
@@ -21,6 +22,7 @@ import com.facebook.react.uimanager.IViewManagerWithChildren;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.yoga.YogaMeasureMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -113,6 +115,20 @@ public class ReactTextViewManager
|
||||
Spannable spanned =
|
||||
TextLayoutManager.getOrCreateSpannableForText(
|
||||
view.getContext(), attributedString, mReactTextViewManagerCallback);
|
||||
|
||||
/**
|
||||
* For natively driven animations for text color, on mount, {@link
|
||||
* UIManager#synchronouslyUpdateViewOnUIThread} may be called before updateState, in which case
|
||||
* the ReactStylesDiffMap will contain the color.
|
||||
*/
|
||||
if (props.hasKey(ViewProps.COLOR) && props.getType(ViewProps.COLOR) == ReadableType.Number) {
|
||||
spanned.setSpan(
|
||||
new ReactForegroundColorSpan(props.getInt(ViewProps.COLOR, 0)),
|
||||
0,
|
||||
spanned.length(),
|
||||
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
}
|
||||
|
||||
view.setSpanned(spanned);
|
||||
|
||||
int textBreakStrategy =
|
||||
|
||||
Reference in New Issue
Block a user