public void showStickyHeader() { mStickyHeader.setVisibility(View.VISIBLE); mStickyHeader.performIncrementalMount(); }
/** * Unmounts a component tree from a component view. * @param lithoView the view to unmount */ public static void unmountComponent(LithoView lithoView) { if (!lithoView.isIncrementalMountEnabled()) { throw new IllegalArgumentException( "In order to test unmounting a Component, it needs to be mounted with " + "incremental mount enabled. Please use a mountComponent() variation that " + "accepts an incrementalMountEnabled argument"); } // Unmounting the component by running incremental mount to a Rect that we certain won't // contain the component. Rect rect = new Rect(99999, 99999, 999999, 999999); lithoView.performIncrementalMount(rect, true); }
/** Performs incremental mount on all {@link LithoView}s within the given View. */ public static void incrementallyMountLithoViews(View view) { if (view instanceof LithoView && ((LithoView) view).isIncrementalMountEnabled()) { ((LithoView) view).performIncrementalMount(); } else if (view instanceof ViewGroup) { for (int i = 0, size = ((ViewGroup) view).getChildCount(); i < size; i++) { final View child = ((ViewGroup) view).getChildAt(i); incrementallyMountLithoViews(child); } } }
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (mIsIncrementalMountEnabled) { mLithoView.performIncrementalMount(); } if (mScrollPosition != null) { mScrollPosition.y = getScrollY(); } }
private static void mountViewIncrementally(View view, boolean processVisibilityOutputs) { assertMainThread(); if (view instanceof LithoView) { final LithoView lithoView = (LithoView) view; if (lithoView.isIncrementalMountEnabled()) { if (!processVisibilityOutputs) { final Rect rect = ComponentsPools.acquireRect(); rect.set(0, 0, view.getWidth(), view.getHeight()); lithoView.performIncrementalMount(rect, false); ComponentsPools.release(rect); } else { lithoView.performIncrementalMount(); } } } else if (view instanceof ViewGroup) { final ViewGroup viewGroup = (ViewGroup) view; for (int i = 0; i < viewGroup.getChildCount(); i++) { final View childView = viewGroup.getChildAt(i); mountViewIncrementally(childView, processVisibilityOutputs); } } }
private static LithoView dispatchVisibilityEvent( ComponentContext context, EventHandler eventHandler, Object eventInstance, Component component) { LithoView lithoView = new LithoView(context); FrameLayout parent = new FrameLayout(context.getAndroidContext()); parent.addView(lithoView); mountComponent( context, lithoView, component, true, 100, 100); lithoView.performIncrementalMount(); try { Whitebox.invokeMethod( component.getEventDispatcher(), "dispatchOnEvent", eventHandler, eventInstance); } catch (Exception e) { throw new RuntimeException(e); } return lithoView; }
@Test public void testNoIncrementalMountWhenNotEnabled() { setupViewBounds( mLithoView, 0, SCROLLING_VIEW_HEIGHT - 5, SCROLLING_VIEW_WIDTH, SCROLLING_VIEW_HEIGHT + 5); when(mLithoView.isIncrementalMountEnabled()).thenReturn(false); IncrementalMountUtils.performIncrementalMount(mViewGroup); verify(mLithoView, never()).performIncrementalMount(any(Rect.class), eq(true)); }
@Test public void testIncrementalMountForWrappedLithoViewAlreadyFullyVisible() { when(mViewGroup.getChildAt(0)).thenReturn(mWrapperView); setupViewBounds(mWrapperView, 0, 10, SCROLLING_VIEW_WIDTH, 20); setupViewBounds(mLithoView, 0, 0, SCROLLING_VIEW_WIDTH, 10); setupLithoViewPreviousBounds(mLithoView, SCROLLING_VIEW_WIDTH, 10); IncrementalMountUtils.performIncrementalMount(mViewGroup); verify(mLithoView, never()).performIncrementalMount(any(Rect.class), eq(true)); }
@Test public void testIncrementalMountForLithoViewVisibleAtTopWithTranslationYFullyOut() { setupViewBounds(mLithoView, 0, -10, SCROLLING_VIEW_WIDTH, 10); setupViewTranslations(mLithoView, 0, -15); IncrementalMountUtils.performIncrementalMount(mViewGroup); verify(mLithoView, never()).performIncrementalMount(any(Rect.class), eq(true)); }
@Test public void testIncrementalMountForLithoViewAlreadyFullyVisible() { setupViewBounds(mLithoView, 0, 10, SCROLLING_VIEW_WIDTH, 20); setupLithoViewPreviousBounds(mLithoView, SCROLLING_VIEW_WIDTH, 10); IncrementalMountUtils.performIncrementalMount(mViewGroup); verify(mLithoView, never()).performIncrementalMount(any(Rect.class), eq(true)); }
@Test public void testChildViewGroupIncrementallyMounted() { final ViewGroup mountedView = mock(ViewGroup.class); when(mountedView.getChildCount()).thenReturn(3); final LithoView childView1 = getMockLithoViewWithBounds(new Rect(5, 10, 20, 30)); when(mountedView.getChildAt(0)).thenReturn(childView1); final LithoView childView2 = getMockLithoViewWithBounds(new Rect(10, 10, 50, 60)); when(mountedView.getChildAt(1)).thenReturn(childView2); final LithoView childView3 = getMockLithoViewWithBounds(new Rect(30, 35, 50, 60)); when(mountedView.getChildAt(2)).thenReturn(childView3); final LithoView lithoView = ComponentTestHelper.mountComponent( TestViewComponent.create(mContext).testView(mountedView)); lithoView.getComponentTree().mountComponent(new Rect(15, 15, 40, 40), true); verify(childView1).performIncrementalMount(); verify(childView2).performIncrementalMount(); verify(childView3).performIncrementalMount(); }
@Test public void testDontThrowWhenLayoutStateIsNull() { final ComponentTree mockComponentTree = mock(ComponentTree.class); mLithoView.setComponentTree(mockComponentTree); mLithoView.requestLayout(); mLithoView.performIncrementalMount(); }
@Test public void testIncrementalMountForLithoViewVisibleAtLeftWithTranslationXFullyIn() { setupViewBounds(mLithoView, -10, 0, 10, SCROLLING_VIEW_HEIGHT); setupViewTranslations(mLithoView, 15, 0); setupLithoViewPreviousBounds(mLithoView, 20, SCROLLING_VIEW_HEIGHT); IncrementalMountUtils.performIncrementalMount(mViewGroup); verify(mLithoView, never()).performIncrementalMount(any(Rect.class), eq(true)); }
@Before public void setUp() { when(mLithoView.isIncrementalMountEnabled()).thenReturn(true); when(mWrapperView.getWrappedView()).thenReturn(mLithoView); when(mViewGroup.getChildCount()).thenReturn(1); when(mViewGroup.getChildAt(0)).thenReturn(mLithoView); when(mViewGroup.getWidth()).thenReturn(SCROLLING_VIEW_WIDTH); when(mViewGroup.getHeight()).thenReturn(SCROLLING_VIEW_HEIGHT); // Can't use verify as the rect is reset when it is released back to the pool, which occurs // before we can check it. doAnswer( new Answer() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { mMountedRect.set((Rect) invocation.getArguments()[0]); return null; } }) .when(mLithoView) .performIncrementalMount(any(Rect.class), eq(true)); }
@Test public void testSetHasTransientStateMountsEverythingIfIncrementalMountEnabled() { final TestComponent child1 = TestViewComponent.create(mContext).build(); final TestComponent child2 = TestDrawableComponent.create(mContext).build(); final LithoView lithoView = mountComponent( mContext, new InlineLayoutSpec() { @Override protected Component onCreateLayout(ComponentContext c) { return Column.create(c) .child(Wrapper.create(c).delegate(child1).widthPx(10).heightPx(10)) .child(Wrapper.create(c).delegate(child2).widthPx(10).heightPx(10)) .build(); } }, true); lithoView.performIncrementalMount(new Rect(0, -10, 10, -5), true); assertThat(child1.isMounted()).isFalse(); assertThat(child2.isMounted()).isFalse(); lithoView.setHasTransientState(true); assertThat(child1.isMounted()).isTrue(); assertThat(child2.isMounted()).isTrue(); }
@Test public void testPerformLayoutWithDifferentBoundsMountsEverything() { final TestComponent child1 = TestViewComponent.create(mContext).build(); final TestComponent child2 = TestDrawableComponent.create(mContext).build(); final LithoView lithoView = mountComponent( mContext, new InlineLayoutSpec() { @Override protected Component onCreateLayout(ComponentContext c) { return Column.create(c) .child(Wrapper.create(c).delegate(child1).widthPx(10).heightPx(10)) .child(Wrapper.create(c).delegate(child2).widthPx(10).heightPx(10)) .build(); } }, true); lithoView.performIncrementalMount(new Rect(0, -10, 10, -5), true); assertThat(child1.isMounted()).isFalse(); assertThat(child2.isMounted()).isFalse(); lithoView.performLayout(false, 0, 0, 200, 200); assertThat(child1.isMounted()).isTrue(); assertThat(child2.isMounted()).isTrue(); }
@Test public void testFocusedOccupiesHalfViewport() { final TestComponent content = create(mContext).build(); final EventHandler<FocusedVisibleEvent> focusedEventHandler = new EventHandler<>(content, 2); final LithoView lithoView = mountComponent( mContext, mLithoView, Column.create(mContext) .child( Wrapper.create(mContext) .delegate(content) .focusedHandler(focusedEventHandler) .widthPx(10) .heightPx(10)) .build(), true, 10, 10); content.getDispatchedEventHandlers().clear(); lithoView.performIncrementalMount(new Rect(LEFT, 0, RIGHT, 4), true); assertThat(content.getDispatchedEventHandlers()) .doesNotContain(focusedEventHandler); lithoView.performIncrementalMount(new Rect(LEFT, 0, RIGHT, 5), true); assertThat(content.getDispatchedEventHandlers()).contains(focusedEventHandler); }
@Test public void testFocusedOccupiesLessThanHalfViewport() { final TestComponent content = create(mContext).build(); final EventHandler<FocusedVisibleEvent> focusedEventHandler = new EventHandler<>(content, 2); final LithoView lithoView = mountComponent( mContext, mLithoView, Column.create(mContext) .child( Wrapper.create(mContext) .delegate(content) .focusedHandler(focusedEventHandler) .widthPx(10) .heightPx(3)) .build(), true, 10, 10); content.getDispatchedEventHandlers().clear(); lithoView.performIncrementalMount(new Rect(LEFT, 0, RIGHT, 2), true); assertThat(content.getDispatchedEventHandlers()) .doesNotContain(focusedEventHandler); lithoView.performIncrementalMount(new Rect(LEFT, 0, RIGHT, 3), true); assertThat(content.getDispatchedEventHandlers()).contains(focusedEventHandler); }
@Test public void testVisibleEvent() { final TestComponent content = create(mContext).build(); final EventHandler<VisibleEvent> visibleEventHandler = new EventHandler<>(content, 2); final LithoView lithoView = mountComponent( mContext, mLithoView, Column.create(mContext) .child( Wrapper.create(mContext) .delegate(content) .visibleHandler(visibleEventHandler) .widthPx(10) .heightPx(5) .marginPx(YogaEdge.TOP, 5)) .build(), true, 10, 5); assertThat(content.getDispatchedEventHandlers()) .doesNotContain(visibleEventHandler); lithoView.performIncrementalMount(new Rect(LEFT, 0, RIGHT, 10), true); assertThat(content.getDispatchedEventHandlers()).contains(visibleEventHandler); }
@Test public void testDetachWithReleasedTreeTriggersInvisibilityItems() { final TestComponent content = create(mContext).build(); final EventHandler<InvisibleEvent> invisibleEventHandler = new EventHandler<>(content, 2); final LithoView lithoView = mountComponent( mContext, Column.create(mContext) .child( Wrapper.create(mContext) .delegate(content) .invisibleHandler(invisibleEventHandler) .widthPx(10) .heightPx(10)) .build(), true); lithoView.performIncrementalMount(new Rect(LEFT, 0, RIGHT, 10), true); lithoView.release(); assertThat(content.getDispatchedEventHandlers()) .doesNotContain(invisibleEventHandler); unbindComponent(lithoView); assertThat(content.getDispatchedEventHandlers()).contains(invisibleEventHandler); }