MountingManager can create views with props in one step instead of two

Summary: Create views with props in one call instead of two. Backwards-compatible.

Reviewed By: shergin

Differential Revision: D14846424

fbshipit-source-id: cb53225579089f7e51d4e9d1fc9fc2e331a994c1
This commit is contained in:
Joshua Gross
2019-04-15 01:41:47 -07:00
committed by Facebook Github Bot
parent b60651dd09
commit bbd925cdd1
8 changed files with 59 additions and 23 deletions

View File

@@ -8,6 +8,7 @@ package com.facebook.react.fabric.mounting;
import android.view.View;
import androidx.annotation.UiThread;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewManagerRegistry;
import java.util.WeakHashMap;
@@ -22,15 +23,16 @@ public final class ContextBasedViewPool implements ViewFactory {
mViewManagerRegistry = viewManagerRegistry;
}
@UiThread
void createView(ThemedReactContext context, String componentName) {
getViewPool(context).createView(componentName, context);
void createView(ThemedReactContext context, ReactStylesDiffMap props, String componentName) {
getViewPool(context).createView(componentName, props, context);
}
@UiThread
@Override
public View getOrCreateView(String componentName, ThemedReactContext context) {
return getViewPool(context).getOrCreateView(componentName, context);
public View getOrCreateView(String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
return getViewPool(context).getOrCreateView(componentName, props, context);
}
@UiThread

View File

@@ -171,10 +171,11 @@ public class MountingManager {
}
@UiThread
public void createView(
public void createViewWithProps(
ThemedReactContext themedReactContext,
String componentName,
int reactTag,
ReadableMap props,
boolean isLayoutable) {
if (mTagToViewState.get(reactTag) != null) {
return;
@@ -183,13 +184,21 @@ public class MountingManager {
View view = null;
ViewManager viewManager = null;
ReactStylesDiffMap diffMap = null;
if (props != null) {
diffMap = new ReactStylesDiffMap(props);
}
if (isLayoutable) {
viewManager = mViewManagerRegistry.get(componentName);
view = mViewFactory.getOrCreateView(componentName, themedReactContext);
view = mViewFactory.getOrCreateView(componentName, diffMap, themedReactContext);
view.setId(reactTag);
}
mTagToViewState.put(reactTag, new ViewState(reactTag, view, viewManager));
ViewState viewState = new ViewState(reactTag, view, viewManager);
viewState.mCurrentProps = diffMap;
mTagToViewState.put(reactTag, viewState);
}
@UiThread
@@ -313,10 +322,7 @@ public class MountingManager {
throw new IllegalStateException("View for component " + componentName + " with tag " + reactTag + " already exists.");
}
createView(reactContext, componentName, reactTag, isLayoutable);
if (isLayoutable) {
updateProps(reactTag, props);
}
createViewWithProps(reactContext, componentName, reactTag, props, isLayoutable);
}
@UiThread

View File

@@ -7,11 +7,12 @@
package com.facebook.react.fabric.mounting;
import android.view.View;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ThemedReactContext;
public interface ViewFactory {
View getOrCreateView(String componentName, ThemedReactContext context);
View getOrCreateView(String componentName, ReactStylesDiffMap props, ThemedReactContext context);
void recycle(ThemedReactContext context, String componentName, View view);

View File

@@ -8,6 +8,7 @@ package com.facebook.react.fabric.mounting;
import androidx.annotation.UiThread;
import android.view.View;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewManagerRegistry;
@@ -22,8 +23,8 @@ public class ViewManagerFactory implements ViewFactory {
@UiThread
@Override
public View getOrCreateView(
String componentName, ThemedReactContext context) {
return mViewManagerRegistry.get(componentName).createView(context, null);
String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
return mViewManagerRegistry.get(componentName).createViewWithProps(context, props, null);
}
@UiThread

View File

@@ -9,6 +9,7 @@ package com.facebook.react.fabric.mounting;
import androidx.annotation.UiThread;
import android.view.View;
import com.facebook.react.common.ClearableSynchronizedPool;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewManagerRegistry;
@@ -25,20 +26,20 @@ public final class ViewPool {
}
@UiThread
void createView(String componentName, ThemedReactContext context) {
void createView(String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
ClearableSynchronizedPool<View> viewPool = getViewPoolForComponent(componentName);
ViewManager viewManager = mViewManagerRegistry.get(componentName);
// TODO: T31905686 Integrate / re-implement jsResponder
View view = viewManager.createView(context, null);
View view = viewManager.createViewWithProps(context, props, null);
viewPool.release(view);
}
@UiThread
View getOrCreateView(String componentName, ThemedReactContext context) {
View getOrCreateView(String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
ClearableSynchronizedPool<View> viewPool = getViewPoolForComponent(componentName);
View view = viewPool.acquire();
if (view == null) {
createView(componentName, context);
createView(componentName, props, context);
view = viewPool.acquire();
}
return view;

View File

@@ -248,7 +248,7 @@ public class NativeViewHierarchyManager {
try {
ViewManager viewManager = mViewManagers.get(className);
View view = viewManager.createView(themedContext, mJSResponderHandler);
View view = viewManager.createViewWithProps(themedContext, null, mJSResponderHandler);
mTagsToViews.put(tag, view);
mTagsToViewManagers.put(tag, viewManager);

View File

@@ -42,10 +42,20 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
/**
* Creates a view and installs event emitters on it.
*/
public final @Nonnull T createView(
private final @Nonnull T createView(
@Nonnull ThemedReactContext reactContext,
JSResponderHandler jsResponderHandler) {
T view = createViewInstance(reactContext);
return this.createViewWithProps(reactContext, null, jsResponderHandler);
}
/**
* Creates a view with knowledge of props.
*/
public @Nonnull T createViewWithProps(
@Nonnull ThemedReactContext reactContext,
ReactStylesDiffMap props,
JSResponderHandler jsResponderHandler) {
T view = createViewInstanceWithProps(reactContext, props);
addEventEmitters(reactContext, view);
if (view instanceof ReactInterceptingViewGroup) {
((ReactInterceptingViewGroup) view).setOnInterceptTouchEventListener(jsResponderHandler);
@@ -53,6 +63,7 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
return view;
}
/**
* @return the name of this view manager. This will be the name used to reference this view
* manager from JavaScript in createReactNativeComponentClass.
@@ -90,6 +101,20 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
*/
protected abstract @Nonnull T createViewInstance(@Nonnull ThemedReactContext reactContext);
/**
* Subclasses should return a new View instance of the proper type.
* This is an optional method that will call createViewInstance for you.
* Override it if you need props upon creation of the view.
* @param reactContext
*/
protected @Nonnull T createViewInstanceWithProps(@Nonnull ThemedReactContext reactContext, ReactStylesDiffMap initialProps) {
T view = createViewInstance(reactContext);
if (initialProps != null) {
updateProperties(view, initialProps);
}
return view;
}
/**
* Called when view is detached from view hierarchy and allows for some additional cleanup by
* the {@link ViewManager} subclass.

View File

@@ -83,7 +83,7 @@ public class SimpleViewPropertyTest {
@Test
public void testOpacity() {
View view = mManager.createView(mThemedContext, new JSResponderHandler());
View view = mManager.createViewWithProps(mThemedContext, buildStyles(), new JSResponderHandler());
mManager.updateProperties(view, buildStyles());
assertThat(view.getAlpha()).isEqualTo(1.0f);
@@ -97,7 +97,7 @@ public class SimpleViewPropertyTest {
@Test
public void testBackgroundColor() {
View view = mManager.createView(mThemedContext, new JSResponderHandler());
View view = mManager.createViewWithProps(mThemedContext, buildStyles(), new JSResponderHandler());
mManager.updateProperties(view, buildStyles());
assertThat(view.getBackground()).isEqualTo(null);