TreeAdapter extends PowerAdapter { public void setExpanded(int position, boolean expanded) { if (mRootAdapter.hasStableIds()) { long itemId = mRootAdapter.getItemId(position); mState.setExpanded(itemId, expanded); } if (position < mEntries.size()) { Entry entry = mEntries.get(position); boolean alreadyExpanded = entry.getAdapter() != null; if (expanded != alreadyExpanded) { entry.setAdapter(expanded ? getChildAdapter(position) : null); } } } TreeAdapter(@NonNull PowerAdapter rootAdapter, @NonNull ChildAdapterSupplier childAdapterSupplier); @NonNull Parcelable saveInstanceState(); void restoreInstanceState(@Nullable Parcelable parcelable); boolean isAutoExpand(); void setAutoExpand(boolean autoExpand); boolean isExpanded(int position); void setExpanded(int position, boolean expanded); boolean toggleExpanded(int position); void setAllExpanded(boolean expanded); @Override int getItemCount(); @Override boolean hasStableIds(); @Override long getItemId(int position); @Override boolean isEnabled(int position); @NonNull @Override Object getItemViewType(int position); @NonNull @Override View newView(@NonNull ViewGroup parent, @NonNull Object viewType); @Override void bindView(
            @NonNull Container container,
            @NonNull View view,
            @NonNull Holder holder,
            @NonNull List<Object> payloads
    );  }
@Test public void expandInvokesGetChildAdapter() { mTreeAdapter.setExpanded(0, true); mTreeAdapter.setExpanded(1, true); mTreeAdapter.setExpanded(2, true); verify(mChildAdapterSupplier).get(0); verify(mChildAdapterSupplier).get(1); verify(mChildAdapterSupplier).get(2); verifyNoMoreInteractions(mChildAdapterSupplier); }
@Test public void collapseRemovesChildItems() { DataObserver observer = registerMockDataObserver(); mTreeAdapter.setExpanded(2, false); verify(observer).onItemRangeRemoved(9, 3); verifyNoMoreInteractions(observer); }
@Test public void collapseStateIsCorrect0() { mTreeAdapter.setExpanded(0, false); verifySubAdapterAllGetCalls() .check(mRootAdapter, 0) .check(mRootAdapter, 1) .check(mChildAdapters.get(1), 0) .check(mChildAdapters.get(1), 1) .check(mChildAdapters.get(1), 2) .check(mRootAdapter, 2) .check(mChildAdapters.get(2), 0) .check(mChildAdapters.get(2), 1) .check(mChildAdapters.get(2), 2) .verify(mTreeAdapter); }
@Test public void collapseStateIsCorrect1() { mTreeAdapter.setExpanded(1, false); verifySubAdapterAllGetCalls() .check(mRootAdapter, 0) .check(mChildAdapters.get(0), 0) .check(mChildAdapters.get(0), 1) .check(mChildAdapters.get(0), 2) .check(mRootAdapter, 1) .check(mRootAdapter, 2) .check(mChildAdapters.get(2), 0) .check(mChildAdapters.get(2), 1) .check(mChildAdapters.get(2), 2) .verify(mTreeAdapter); }
@Test public void collapseStateIsCorrect2() { mTreeAdapter.setExpanded(2, false); verifySubAdapterAllGetCalls() .check(mRootAdapter, 0) .check(mChildAdapters.get(0), 0) .check(mChildAdapters.get(0), 1) .check(mChildAdapters.get(0), 2) .check(mRootAdapter, 1) .check(mChildAdapters.get(1), 0) .check(mChildAdapters.get(1), 1) .check(mChildAdapters.get(1), 2) .check(mRootAdapter, 2) .verify(mTreeAdapter); }
@Test public void childNotificationsAreIgnoredWhenCollapsed() { DataObserver observer = mock(DataObserver.class); mTreeAdapter.setExpanded(2, false); mTreeAdapter.setExpanded(0, false); mTreeAdapter.registerDataObserver(observer); mChildAdapters.get(0).remove(0, 1); mChildAdapters.get(2).insert(1, 1); verifyZeroInteractions(observer); }