/** * For testing purposes, props are only compared if both subcomponents supply them. Otherwise, * just ignore them. */ private static boolean arePropsEqual(Component thatComponent, Component thisComponent) { return thatComponent == null || thisComponent == null || thatComponent.isEquivalentTo(thisComponent); }
/** * Whether the component needs updating. * <p> * For layout components, the framework will verify that none of the children of the component * need updating, and that both components have the same number of children. Therefore this * method just needs to determine any changes to the top-level component that would cause it to * need to be updated (for example, a click handler was added). * <p> * For mount specs, the framework does nothing extra and this method alone determines whether the * component is updated or not. * @param previous the previous component to compare against. * @param next the component that is now in use. * @return true if the component needs an update, false otherwise. */ protected boolean shouldUpdate(Component previous, Component next) { return !previous.isEquivalentTo(next); }
private static boolean areComponentCollectionsEquals( final int level, final Collection c1, final Collection c2) { if (level < 1) { throw new IllegalArgumentException("Level cannot be < 1"); } if (c1 == null && c2 == null) { return true; } if (c1 != null ? (c2 == null || c1.size() != c2.size()) : c2 != null) { return false; } final Iterator i1 = c1.iterator(); final Iterator i2 = c2.iterator(); while (i1.hasNext() && i2.hasNext()) { if (level == 1) { if (!((Component) i1.next()).isEquivalentTo((Component) i2.next())) { return false; } } else { if (!areComponentCollectionsEquals( level - 1, (Collection) i1.next(), (Collection) i2.next())) { return false; } } } return true; }
if (!children.get(i).isEquivalentTo(row.children.get(i))) { return false;
if (!children.get(i).isEquivalentTo(column.children.get(i))) { return false;
/** * @return A concatenated string of all text content within the underlying LithoView. * Null if the node doesn't have an associated LithoView. */ @Nullable public String getTextContent() { final LithoView lithoView = getLithoView(); final Component component = getComponent(); if (lithoView == null) { return null; } final MountState mountState = lithoView.getMountState(); final StringBuilder sb = new StringBuilder(); for (int i = 0, size = mountState.getItemCount(); i < size; i++) { final MountItem mountItem = mountState.getItemAt(i); final Component mountItemComponent = mountItem == null ? null : mountItem.getComponent(); if (mountItemComponent != null && mountItemComponent.isEquivalentTo(component)) { final Object content = mountItem.getBaseContent(); if (content instanceof TextContent) { for (CharSequence charSequence : ((TextContent) content).getTextItems()) { sb.append(charSequence); } } else if (content instanceof TextView) { sb.append(((TextView) content).getText()); } } } return sb.toString(); }
@ShouldUpdate(onMount = true) static boolean shouldUpdate( @Prop Diff<Component> childComponent, @Prop(optional = true) Diff<Boolean> scrollbarEnabled, @Prop(optional = true) Diff<Boolean> scrollbarFadingEnabled, @Prop(optional = true) Diff<Boolean> fillViewport, @Prop(optional = true) Diff<Boolean> nestedScrollingEnabled, @Prop(optional = true) Diff<Boolean> incrementalMountEnabled) { return !childComponent.getPrevious().isEquivalentTo(childComponent.getNext()) || !scrollbarEnabled.getPrevious().equals(scrollbarEnabled.getNext()) || !scrollbarFadingEnabled.getPrevious().equals(scrollbarFadingEnabled.getNext()) || !fillViewport.getPrevious().equals(fillViewport.getNext()) || !nestedScrollingEnabled.getPrevious().equals(nestedScrollingEnabled.getNext()) || !incrementalMountEnabled.getPrevious().equals(incrementalMountEnabled.getNext()); }
/** * @return The {@link ComponentHost} that wraps this component or null if one cannot be found. */ @Nullable public ComponentHost getComponentHost() { final LithoView lithoView = getLithoView(); final Component component = getComponent(); if (lithoView == null) { return null; } for (int i = 0, size = lithoView.getMountState().getItemCount(); i < size; i++) { final MountItem mountItem = lithoView.getMountState().getItemAt(i); final Component mountItemComponent = mountItem == null ? null : mountItem.getComponent(); if (mountItemComponent != null && mountItemComponent.isEquivalentTo(component)) { return mountItem.getHost(); } } return null; }
@Test public void testNoUpdate() { Component nextComponent = mock(Component.class); Component prevComponent = mock(Component.class); when(prevComponent.isEquivalentTo(nextComponent)).thenReturn(true); mComponentDiff.init(prevComponent, nextComponent); mStickyDiff.init(true, true); mSpanSizeDiff.init(1, 1); mIsFullSpanDiff.init(true, true); mCustomAttributesDiff.init(null, null); mDataDiff.init(1, 1); SingleComponentSectionSpec.onCreateChangeSet( mSectionContext, mChangeSet, mComponentDiff, mStickyDiff, mSpanSizeDiff, mIsFullSpanDiff, mCustomAttributesDiff, mDataDiff); assertThat(mChangeSet.getChangeCount()).isEqualTo(0); }
@Test public void testUpdateComponent() { Component nextComponent = mock(Component.class); Component prevComponent = mock(Component.class); when(prevComponent.isEquivalentTo(nextComponent)).thenReturn(false); mComponentDiff.init(prevComponent, nextComponent); mStickyDiff.init(true, true); mSpanSizeDiff.init(2, 2); mIsFullSpanDiff.init(true, true); mCustomAttributesDiff.init(null, null); mDataDiff.init(1, 2); SingleComponentSectionSpec.onCreateChangeSet( mSectionContext, mChangeSet, mComponentDiff, mStickyDiff, mSpanSizeDiff, mIsFullSpanDiff, mCustomAttributesDiff, mDataDiff); Change change = verifyChangeSetAndGetTheChange(mChangeSet); assertThat(change.getType()).isEqualTo(Change.UPDATE); assertThat(change.getRenderInfo().getComponent()).isEqualTo(nextComponent); assertThat(change.getRenderInfo().isSticky()).isTrue(); assertThat(change.getRenderInfo().getSpanSize()).isEqualTo(2); assertThat(change.getRenderInfo().isFullSpan()).isTrue(); assertThat(change.getPrevData()).isEqualTo(ImmutableList.of(1)); assertThat(change.getNextData()).isEqualTo(ImmutableList.of(2)); }
@Test public void testUpdateCustomAttributes() { Component component = mock(Component.class); when(component.isEquivalentTo(any())).thenReturn(true); mComponentDiff.init(component, component); mStickyDiff.init(true, true);
|| prevSpanSize != nextSpanSize || isPrevFullSpan != isNextFullSpan || !component.getPrevious().isEquivalentTo(component.getNext()) || !customAttributesEqual) { changeSet.update(