Files
react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java
T
Christoph Nakazawa 1ca9a95537 Move WebView Android files to FB internal
Summary: This moves the Java files to FB internal and updates all the buck files

Reviewed By: TheSavior

Differential Revision: D14622521

fbshipit-source-id: a8d293e9f9e08868cca3ed2986a08d0db16dec15
2019-04-02 11:19:47 -07:00

217 lines
7.8 KiB
Java

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager;
import android.view.View;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.touch.JSResponderHandler;
import com.facebook.react.touch.ReactInterceptingViewGroup;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.react.uimanager.annotations.ReactPropertyHolder;
import com.facebook.yoga.YogaMeasureMode;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Class responsible for knowing how to create and update catalyst Views of a given type. It is also
* responsible for creating and updating CSSNodeDEPRECATED subclasses used for calculating position and size
* for the corresponding native view.
*/
@ReactPropertyHolder
public abstract class ViewManager<T extends View, C extends ReactShadowNode>
extends BaseJavaModule {
public final void updateProperties(@Nonnull T viewToUpdate, ReactStylesDiffMap props) {
ViewManagerPropertyUpdater.updateProps(this, viewToUpdate, props);
onAfterUpdateTransaction(viewToUpdate);
}
/**
* Creates a view and installs event emitters on it.
*/
public final @Nonnull T createView(
@Nonnull ThemedReactContext reactContext,
JSResponderHandler jsResponderHandler) {
T view = createViewInstance(reactContext);
addEventEmitters(reactContext, view);
if (view instanceof ReactInterceptingViewGroup) {
((ReactInterceptingViewGroup) view).setOnInterceptTouchEventListener(jsResponderHandler);
}
return view;
}
/**
* @return the name of this view manager. This will be the name used to reference this view
* manager from JavaScript in createReactNativeComponentClass.
*/
public abstract @Nonnull String getName();
/**
* This method should return a subclass of {@link ReactShadowNode} which will be then used for
* measuring position and size of the view. In most of the cases this should just return an
* instance of {@link ReactShadowNode}
*/
public C createShadowNodeInstance() {
throw new RuntimeException("ViewManager subclasses must implement createShadowNodeInstance()");
}
public @Nonnull C createShadowNodeInstance(@Nonnull ReactApplicationContext context) {
return createShadowNodeInstance();
}
/**
* This method should return {@link Class} instance that represent type of shadow node that this
* manager will return from {@link #createShadowNodeInstance}.
*
* This method will be used in the bridge initialization phase to collect properties exposed using
* {@link ReactProp} (or {@link ReactPropGroup}) annotation from the {@link ReactShadowNode}
* subclass specific for native view this manager provides.
*
* @return {@link Class} object that represents type of shadow node used by this view manager.
*/
public abstract Class<? extends C> getShadowNodeClass();
/**
* Subclasses should return a new View instance of the proper type.
* @param reactContext
*/
protected abstract @Nonnull T createViewInstance(@Nonnull ThemedReactContext reactContext);
/**
* Called when view is detached from view hierarchy and allows for some additional cleanup by
* the {@link ViewManager} subclass.
*/
public void onDropViewInstance(@Nonnull T view) {
}
/**
* Subclasses can override this method to install custom event emitters on the given View. You
* might want to override this method if your view needs to emit events besides basic touch events
* to JS (e.g. scroll events).
*/
protected void addEventEmitters(@Nonnull ThemedReactContext reactContext, @Nonnull T view) {
}
/**
* Callback that will be triggered after all properties are updated in current update transaction
* (all @ReactProp handlers for properties updated in current transaction have been called). If
* you want to override this method you should call super.onAfterUpdateTransaction from it as
* the parent class of the ViewManager may rely on callback being executed.
*/
protected void onAfterUpdateTransaction(@Nonnull T view) {
}
/**
* Subclasses can implement this method to receive an optional extra data enqueued from the
* corresponding instance of {@link ReactShadowNode} in
* {@link ReactShadowNode#onCollectExtraUpdates}.
*
* Since css layout step and ui updates can be executed in separate thread apart of setting
* x/y/width/height this is the recommended and thread-safe way of passing extra data from css
* node to the native view counterpart.
*
* TODO(7247021): Replace updateExtraData with generic update props mechanism after D2086999
*/
public abstract void updateExtraData(@Nonnull T root, Object extraData);
/**
* Subclasses may use this method to receive events/commands directly from JS through the
* {@link UIManager}. Good example of such a command would be {@code scrollTo} request with
* coordinates for a {@link ScrollView} instance.
*
* @param root View instance that should receive the command
* @param commandId code of the command
* @param args optional arguments for the command
*/
public void receiveCommand(@Nonnull T root, int commandId, @Nullable ReadableArray args) {
}
/**
* Subclasses of {@link ViewManager} that expect to receive commands through
* {@link UIManagerModule#dispatchViewManagerCommand} should override this method returning the
* map between names of the commands and IDs that are then used in {@link #receiveCommand} method
* whenever the command is dispatched for this particular {@link ViewManager}.
*
* @return map of string to int mapping of the expected commands
*/
public @Nullable Map<String, Integer> getCommandsMap() {
return null;
}
/**
* Returns a map of config data passed to JS that defines eligible events that can be placed on
* native views. This should return bubbling directly-dispatched event types and specify what
* names should be used to subscribe to either form (bubbling/capturing).
*
* Returned map should be of the form:
* {
* "onTwirl": {
* "phasedRegistrationNames": {
* "bubbled": "onTwirl",
* "captured": "onTwirlCaptured"
* }
* }
* }
*/
public @Nullable Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
return null;
}
/**
* Returns a map of config data passed to JS that defines eligible events that can be placed on
* native views. This should return non-bubbling directly-dispatched event types.
*
* Returned map should be of the form:
* {
* "onTwirl": {
* "registrationName": "onTwirl"
* }
* }
*/
public @Nullable Map<String, Object> getExportedCustomDirectEventTypeConstants() {
return null;
}
/**
* Returns a map of view-specific constants that are injected to JavaScript. These constants are
* made accessible via UIManager.<ViewName>.Constants.
*/
public @Nullable Map<String, Object> getExportedViewConstants() {
return null;
}
public Map<String, String> getNativeProps() {
return ViewManagerPropertyUpdater.getNativeProps(getClass(), getShadowNodeClass());
}
/**
*
*/
public @Nullable Object updateLocalData(@Nonnull T view, ReactStylesDiffMap props, ReactStylesDiffMap localData) {
return null;
}
public long measure(
ReactContext context,
ReadableMap localData,
ReadableMap props,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode) {
return 0;
}
}