public final void updateView(UIImplementation uiImplementation) { if (mConnectedViewTag == -1) { throw new IllegalStateException("Node has not been attached to a view"); } JavaOnlyMap propsMap = new JavaOnlyMap(); for (Map.Entry<String, Integer> entry : mPropMapping.entrySet()) { @Nullable AnimatedNode node = mNativeAnimatedNodesManager.getNodeById(entry.getValue()); if (node == null) { throw new IllegalArgumentException("Mapped property node does not exists"); } else if (node instanceof StyleAnimatedNode) { ((StyleAnimatedNode) node).collectViewUpdates(propsMap); } else if (node instanceof ValueAnimatedNode) { propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).getValue()); } else { throw new IllegalArgumentException("Unsupported type of node used in property node " + node.getClass()); } } // TODO: Reuse propsMap and stylesDiffMap objects - note that in subsequent animation steps // for a given node most of the time we will be creating the same set of props (just with // different values). We can take advantage on that and optimize the way we allocate property // maps (we also know that updating view props doesn't retain a reference to the styles object). uiImplementation.synchronouslyUpdateViewOnUIThread( mConnectedViewTag, new ReactStylesDiffMap(propsMap)); }
public UIManagerModule getUIManagerModule() { ReactApplicationContext reactContext = ReactTestHelper.createCatalystContextForTest(); List<ViewManager> viewManagers = Arrays.asList( new ViewManager[] { new ReactTextInputManager(), }); DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics(); DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics); DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics); UIManagerModule uiManagerModule = new UIManagerModule( reactContext, viewManagers, new UIImplementation(reactContext, viewManagers)); uiManagerModule.onHostResume(); return uiManagerModule; }
public UIManagerModule getUIManagerModule() { ReactApplicationContext reactContext = ReactTestHelper.createCatalystContextForTest(); DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics(); DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics); DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics); List<ViewManager> viewManagers = Arrays.asList( new ViewManager[] { new ReactTextViewManager(), new ReactRawTextManager(), }); UIManagerModule uiManagerModule = new UIManagerModule( reactContext, viewManagers, new UIImplementation(reactContext, viewManagers)); uiManagerModule.onHostResume(); return uiManagerModule; }
public final void updateView(UIImplementation uiImplementation) { if (mConnectedViewTag == -1) { throw new IllegalStateException("Node has not been attached to a view"); } JavaOnlyMap propsMap = new JavaOnlyMap(); for (Map.Entry<String, Integer> entry : mPropMapping.entrySet()) { @Nullable AnimatedNode node = mNativeAnimatedNodesManager.getNodeById(entry.getValue()); if (node == null) { throw new IllegalArgumentException("Mapped property node does not exists"); } else if (node instanceof StyleAnimatedNode) { ((StyleAnimatedNode) node).collectViewUpdates(propsMap); } else if (node instanceof ValueAnimatedNode) { propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).mValue); } else { throw new IllegalArgumentException("Unsupported type of node used in property node " + node.getClass()); } } // TODO: Reuse propsMap and stylesDiffMap objects - note that in subsequent animation steps // for a given node most of the time we will be creating the same set of props (just with // different values). We can take advantage on that and optimize the way we allocate property // maps (we also know that updating view props doesn't retain a reference to the styles object). uiImplementation.synchronouslyUpdateViewOnUIThread( mConnectedViewTag, new ReactStylesDiffMap(propsMap)); }
@Override public void initialize() { // Safe to acquire choreographer here, as initialize() is invoked from UI thread. mReactChoreographer = ReactChoreographer.getInstance(); ReactApplicationContext reactCtx = getReactApplicationContext(); UIImplementation uiImplementation = reactCtx.getNativeModule(UIManagerModule.class).getUIImplementation(); final NativeAnimatedNodesManager nodesManager = new NativeAnimatedNodesManager(uiImplementation); mAnimatedFrameCallback = new GuardedChoreographerFrameCallback(reactCtx) { @Override protected void doFrameGuarded(final long frameTimeNanos) { ArrayList<UIThreadOperation> operations; synchronized (mOperationsCopyLock) { operations = mReadyOperations; mReadyOperations = null; } if (operations != null) { for (int i = 0, size = operations.size(); i < size; i++) { operations.get(i).execute(nodesManager); } } if (nodesManager.hasActiveAnimations()) { nodesManager.runUpdates(frameTimeNanos); } // TODO: Would be great to avoid adding this callback in case there are no active animations // and no outstanding tasks on the operations queue. Apparently frame callbacks can only // be posted from the UI thread and therefore we cannot schedule them directly from // @ReactMethod methods Assertions.assertNotNull(mReactChoreographer).postFrameCallback( ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, mAnimatedFrameCallback); } }; reactCtx.addLifecycleEventListener(this); }
public NativeAnimatedNodesManager(UIImplementation uiImplementation) { mUIImplementation = uiImplementation; }