private BitSet calculateSkipMounting(LayoutState layoutState) { if (!ComponentsConfiguration.createPhantomLayoutOutputsForTransitions) { return sEmptyBitSet; } final BitSet skipMounting = new BitSet(); for (int index = layoutState.getMountableOutputCount() - 1; index >= 0; index--) { if (shouldSkipMounting(layoutState, index)) { skipMounting.set(index); } } return skipMounting; }
private void setupPreviousMountableOutputData(LayoutState layoutState, Rect localVisibleRect) { if (localVisibleRect.isEmpty()) { return; } final ArrayList<LayoutOutput> layoutOutputTops = layoutState.getMountableOutputTops(); final ArrayList<LayoutOutput> layoutOutputBottoms = layoutState.getMountableOutputBottoms(); final int mountableOutputCount = layoutState.getMountableOutputCount(); mPreviousTopsIndex = layoutState.getMountableOutputCount(); for (int i = 0; i < mountableOutputCount; i++) { if (localVisibleRect.bottom <= layoutOutputTops.get(i).getBounds().top) { mPreviousTopsIndex = i; break; } } mPreviousBottomsIndex = layoutState.getMountableOutputCount(); for (int i = 0; i < mountableOutputCount; i++) { if (localVisibleRect.top < layoutOutputBottoms.get(i).getBounds().bottom) { mPreviousBottomsIndex = i; break; } } }
private int findLastDescendantIndex(LayoutState layoutState, int index) { final LayoutOutput host = layoutState.getMountableOutputAt(index); final long hostId = host.getId(); for (int i = index + 1, size = layoutState.getMountableOutputCount(); i < size; i++) { final LayoutOutput layoutOutput = layoutState.getMountableOutputAt(i); // Walk up the parents looking for the host's id: if we find it, it's a descendant. If we // reach the root, then it's not a descendant and we can stop. long curentHostId = layoutOutput.getHostMarker(); while (curentHostId != hostId) { if (curentHostId == ROOT_HOST_ID) { return i - 1; } final int parentIndex = layoutState.getLayoutOutputPositionForId(curentHostId); final LayoutOutput parent = layoutState.getMountableOutputAt(parentIndex); curentHostId = parent.getHostMarker(); } } return layoutState.getMountableOutputCount() - 1; }
private static void assertOutputsState( LayoutState layoutState, @LayoutOutput.UpdateState int state) { assertThat(STATE_DIRTY).isEqualTo(layoutState.getMountableOutputAt(0).getUpdateState()); for (int i = 1; i < layoutState.getMountableOutputCount(); i++) { LayoutOutput output = layoutState.getMountableOutputAt(i); assertThat(state).isEqualTo(output.getUpdateState()); } }
@Test public void testLayoutOutputsForRootInteractiveLayoutSpecs() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c).child(TestDrawableComponent.create(c)).wrapInView().build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(2); }
@Test public void testLayoutOutputForRootWithNullLayout() { final Component componentWithNullLayout = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return null; } }; final LayoutState layoutState = calculateLayoutState( application, componentWithNullLayout, -1, makeSizeSpec(350, EXACTLY), makeSizeSpec(200, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(0); }
@Test public void testNoUnnecessaryLayoutOutputsForLayoutSpecs() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return Column.create(c) .child(Column.create(c).child(TestDrawableComponent.create(c))) .build(); } }; final LayoutState layoutState = calculateLayoutState( RuntimeEnvironment.application, component, -1, SizeSpec.makeSizeSpec(100, SizeSpec.EXACTLY), SizeSpec.makeSizeSpec(100, SizeSpec.EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(2); }
@Test public void testLayoutOutputsForComponentWithBorderColorNoBorderWidth() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child(TestDrawableComponent.create(c)) .border(Border.create(c).color(ALL, GREEN).build()) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); // No layout output generated related with borders // if borderColor is supplied but not borderWidth. assertThat(layoutState.getMountableOutputCount()).isEqualTo(2); }
@Test public void testLayoutOutputsForComponentWithBorderWidthNoBorderColor() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child(TestDrawableComponent.create(c)) .border(Border.create(c).widthPx(ALL, 10).build()) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); // No layout output generated related with borders // if borderWidth supplied but not borderColor. assertThat(layoutState.getMountableOutputCount()).isEqualTo(2); }
@Test public void testLayoutComponentForNestedTreeChildWithNullLayout() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c).paddingPx(ALL, 2).child(new TestNullLayoutComponent()).build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(350, EXACTLY), makeSizeSpec(200, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(1); final Rect mountBounds = new Rect(); assertThat(isHostComponent(getComponentAt(layoutState, 0))).isTrue(); layoutState.getMountableOutputAt(0).getMountBounds(mountBounds); assertThat(mountBounds).isEqualTo(new Rect(0, 0, 350, 200)); }
@Test public void testLayoutOutputsForComponentWithBorderWidthAllAndBorderColor() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child(TestDrawableComponent.create(c)) .border(Border.create(c).widthPx(ALL, 10).color(ALL, GREEN).build()) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(3); // Output at index 1 is BorderColorDrawable component. assertThat(getComponentAt(layoutState, 2)).isInstanceOf(DrawableComponent.class); }
@Test public void testLayoutOutputsForComponentWithBorderWidthTopAndBorderColor() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child(TestDrawableComponent.create(c)) .border(Border.create(c).widthPx(TOP, 10).color(TOP, GREEN).build()) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(3); // Output at index 1 is BorderColorDrawable component. assertThat(getComponentAt(layoutState, 2)).isInstanceOf(DrawableComponent.class); }
@Test public void testLayoutOutputsWithInteractiveLayoutSpecAsLeafs() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child(TestDrawableComponent.create(c)) .child(create(c).child(TestLayoutComponent.create(c)).wrapInView()) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(350, EXACTLY), makeSizeSpec(200, EXACTLY)); // Check total layout outputs. assertThat(layoutState.getMountableOutputCount()).isEqualTo(3); assertThat(isHostComponent(getComponentAt(layoutState, 0))).isTrue(); assertThat(getComponentAt(layoutState, 1)).isInstanceOf(TestDrawableComponent.class); assertThat(isHostComponent(getComponentAt(layoutState, 2))).isTrue(); }
@Test public void testLayoutOutputsForSelected() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child( create(c).child(TestDrawableComponent.create(c)).focusable(true).selected(true)) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(3); assertThat(layoutState.getMountableOutputAt(0).getNodeInfo()).isNull(); assertThat(layoutState.getMountableOutputAt(1).getNodeInfo().getSelectedState()) .isEqualTo(SELECTED_SET_TRUE); }
@Test public void testLayoutOutputsForFocusable() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child(create(c).child(TestDrawableComponent.create(c)).focusable(true)) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(3); assertThat(layoutState.getMountableOutputAt(0).getNodeInfo()).isNull(); assertThat(layoutState.getMountableOutputAt(1).getNodeInfo().getFocusState()).isEqualTo(FOCUS_SET_TRUE); }
@Test public void testLayoutOutputsForSelectedOnRoot() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c).child(TestDrawableComponent.create(c)).selected(true).build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(2); final long hostMarkerZero = layoutState.getMountableOutputAt(0).getHostMarker(); assertThat(layoutState.getMountableOutputAt(1).getHostMarker()).isEqualTo(hostMarkerZero); assertThat(isHostComponent(getComponentAt(layoutState, 0))).isTrue(); assertThat(getComponentAt(layoutState, 1)).isInstanceOf(TestDrawableComponent.class); assertThat(layoutState.getMountableOutputAt(0).getNodeInfo().getSelectedState()) .isEqualTo(SELECTED_SET_TRUE); }
@Test public void testLayoutOutputsForFocusableOnRoot() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c).child(TestDrawableComponent.create(c)).focusable(true).build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(2); final long hostMarkerZero = layoutState.getMountableOutputAt(0).getHostMarker(); assertThat(layoutState.getMountableOutputAt(1).getHostMarker()).isEqualTo(hostMarkerZero); assertThat(isHostComponent(getComponentAt(layoutState, 0))).isTrue(); assertThat(getComponentAt(layoutState, 1)).isInstanceOf(TestDrawableComponent.class); assertThat(layoutState.getMountableOutputAt(0).getNodeInfo().getFocusState()).isEqualTo(FOCUS_SET_TRUE); }
@Test public void testLayoutOutputsForComponentWithBackgrounds() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .backgroundColor(0xFFFF0000) .foregroundColor(0xFFFF0000) .child(TestDrawableComponent.create(c)) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(4); // First and third output are the background and the foreground assertThat(getComponentAt(layoutState, 1)).isInstanceOf(DrawableComponent.class); assertThat(getComponentAt(layoutState, 3)).isInstanceOf(DrawableComponent.class); }
@Test public void testLayoutOutputsForSpecsWithTouchHandling() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c) .child( create(c) .child(TestDrawableComponent.create(c)) .touchHandler(c.newEventHandler(1))) .build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(3); final NodeInfo nodeInfo = layoutState.getMountableOutputAt(1).getNodeInfo(); assertThat(nodeInfo).isNotNull(); assertThat(nodeInfo.getTouchHandler()).isNotNull(); assertThat(nodeInfo.getClickHandler()).isNull(); assertThat(nodeInfo.getLongClickHandler()).isNull(); assertThat(nodeInfo.getFocusChangeHandler()).isNull(); }
@Test public void testLayoutOutputsForForceWrappedComponent() { final Component component = new InlineLayoutSpec() { @Override protected Component onCreateLayout(final ComponentContext c) { return create(c).child(TestDrawableComponent.create(c).wrapInView()).build(); } }; final LayoutState layoutState = calculateLayoutState( application, component, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(layoutState.getMountableOutputCount()).isEqualTo(3); assertThat(getComponentAt(layoutState, 0)).isInstanceOf(HostComponent.class); assertThat(getComponentAt(layoutState, 1)).isInstanceOf(HostComponent.class); assertThat(getComponentAt(layoutState, 2)).isInstanceOf(TestDrawableComponent.class); }