public GroupAdapterViewTypeDelegate(List<AdapterViewTypeDelegate> delegates) { childAdapterViewTypeDelegates.addAll(delegates); int childViewType = 0; for (AdapterViewTypeDelegate delegate : childAdapterViewTypeDelegates) { if (delegate.getViewType() != RecyclerView.INVALID_TYPE) { throw new IllegalStateException("Do not reuse AdapterViewTypeDelegate instances"); } delegate.setViewType(childViewType); childViewType++; delegate.addFeatureEventListener(this::fireEvent); childDiffUtilComparators.add(delegate.createDiffUtilComparator()); childViewHolderCache.add(new ArrayDeque<>()); } }
/** * Called by the Adapter from {@link Adapter#onBindViewHolder(RecyclerView.ViewHolder, int, * List)}. Maps the data back to the view, using a non empty PayLoad. * * <p>The default implementation discards the {@code payloads} information and just calls {@link * #bindViewHolder(RecyclerView.ViewHolder, MODEL)}. Override, if you want to implement more * fine-grained, payload based updates. * * @param holder The ViewHolder which should be updated to represent the contents of the item at * the given position in the data set. * @param model The Model containing all the data for the ViewHolder to bind to. * @param payloads the payload of changes. An empty list means the view holder needs full re-bind. */ public void bindViewHolder(HOLDER holder, MODEL model, List<Object> payloads) { bindViewHolder(holder, model); }
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return mapViewTypeToAdapterViewTypeDelegate.get(viewType).createViewHolder(parent); }
private void registerAdapterViewTypeDelegates(List<FeatureController<MODEL>> featureControllers) { for (FeatureController<MODEL> featureController : featureControllers) { for (AdapterViewTypeDelegate delegate : featureController.getAdapterViewTypeDelegates()) { // assign unique view type delegate.setViewType(mapViewTypeToAdapterViewTypeDelegate.size()); // register delegate mapViewTypeToAdapterViewTypeDelegate.put(delegate.getViewType(), delegate); // register item comparator mapViewTypeToItemComparator.put( delegate.getViewType(), delegate.createDiffUtilComparator()); } } }
private TargetGroupAdapterViewTypeDelegate createTargetDelegateWithState(List<AdapterViewTypeDelegate> delegates, List<ViewItem> viewItems, List<RecyclerView.ViewHolder> childViewHolders, GroupViewHolder groupHolder) { for (int i = 0; i < viewItems.size(); i++) { ViewItem viewItem = viewItems.get(i); RecyclerView.ViewHolder childViewHolder = childViewHolders.get(i); AdapterViewTypeDelegate delegate = delegates.get(viewItem.viewType); expect(delegate.createViewHolder(groupHolder.viewGroup)).andReturn(childViewHolder).times(1); delegate.bindViewHolder(childViewHolder, viewItem.model); } replayAll(); TargetGroupAdapterViewTypeDelegate target = new TargetGroupAdapterViewTypeDelegate(delegates); target.bindViewHolder(groupHolder, viewItems); resetAll(); return target; }
delegates.get(0).unbindViewHolder(childViewHolders.get(0)); delegates.get(1).unbindViewHolder(childViewHolders.get(1)); delegates.get(0).unbindViewHolder(childViewHolders.get(2)); delegates.get(1).unbindViewHolder(childViewHolders.get(3)); delegates.get(0).bindViewHolder(childViewHolders.get(0), viewItems.get(0).model); delegates.get(1).bindViewHolder(childViewHolders.get(1), viewItems.get(1).model); delegates.get(0).bindViewHolder(childViewHolders.get(2), viewItems.get(2).model); delegates.get(1).bindViewHolder(childViewHolders.get(3), viewItems.get(3).model);
/** * Creates a new item. * * @param model the instance of the {@code MODEL} class. * @param adapterViewTypeDelegate the {@link AdapterViewTypeDelegate} associated with this item. */ public ViewItem(MODEL model, AdapterViewTypeDelegate adapterViewTypeDelegate) { this.model = model; this.viewType = adapterViewTypeDelegate.getViewType(); } }
@Override public void onViewRecycled(ViewHolder holder) { //noinspection unchecked mapViewTypeToAdapterViewTypeDelegate.get(holder.getItemViewType()).unbindViewHolder(holder); }
@Test public void createItemComparatorForType_should_returnNonNullComparator() { //GIVEN AdapterViewTypeDelegate<?, String> stubAdapterViewTypeDelegate = new StubAdapterViewTypeDelegate(); //WHEN final DiffUtilComparator diffUtilComparator = stubAdapterViewTypeDelegate.createDiffUtilComparator(); //THEN assertThat(diffUtilComparator, not(nullValue())); } }
/** * Adds a {@link FeatureEventListener} to all the {@link AdapterViewTypeDelegate} returned by * {@link #getAdapterViewTypeDelegates()}. * * @param featureEventListener the listener to be added. */ public void addFeatureEventListener(FeatureEventListener featureEventListener) { featureEventSource.addFeatureEventListener(featureEventListener); for (AdapterViewTypeDelegate adapterViewTypeDelegate : getAdapterViewTypeDelegates()) { adapterViewTypeDelegate.addFeatureEventListener(featureEventListener); } }
private ViewItem<ChildModel> createViewItem(ChildModel model, int viewType) { AdapterViewTypeDelegate tempDelegate = new StubAdapterViewTypeDelegate(); tempDelegate.setViewType(viewType); return new ViewItem<>(model, tempDelegate); }
expect(delegates.get(0).createViewHolder(groupHolder.viewGroup)).andReturn(childViewHolders.get(0)); expect(delegates.get(1).createViewHolder(groupHolder.viewGroup)).andReturn(childViewHolders.get(1)); delegates.get(0).bindViewHolder(childViewHolders.get(0), viewItems.get(0).model); delegates.get(1).bindViewHolder(childViewHolders.get(1), viewItems.get(1).model);
delegates.get(0).unbindViewHolder(childViewHolders.get(0)); delegates.get(1).unbindViewHolder(childViewHolders.get(1)); delegates.get(0).unbindViewHolder(childViewHolders.get(2)); delegates.get(1).unbindViewHolder(childViewHolders.get(3)); delegates.get(0).bindViewHolder(childViewHolders.get(0), viewItems.get(0).model); delegates.get(1).bindViewHolder(childViewHolders.get(1), viewItems.get(1).model); delegates.get(0).bindViewHolder(childViewHolders.get(2), viewItems.get(2).model); delegates.get(1).bindViewHolder(childViewHolders.get(3), viewItems.get(3).model);
public void registerFeatureDecoration(FeatureItemDecoration decoration, AdapterViewTypeDelegate viewTypeDelegate) { viewTypeDecorationMap.put(viewTypeDelegate.getViewType(), decoration); }
private void unbindChildView(View childItemView) { ChildViewState childViewState = getChildViewState(childItemView); AdapterViewTypeDelegate delegate = childAdapterViewTypeDelegates.get(childViewState.viewItem.viewType); delegate.unbindViewHolder(childViewState.childViewHolder); childViewHolderCache.get(childViewState.viewItem.viewType).offer(childViewState.childViewHolder); childViewState.clearViewState(); }
private AdapterViewTypeDelegate createValidAdapterViewTypeDelegate(int expectedViewType) { AdapterViewTypeDelegate delegate = createMock(AdapterViewTypeDelegate.class); expect(delegate.getViewType()).andStubReturn(RecyclerView.INVALID_TYPE); delegate.setViewType(expectedViewType); delegate.addFeatureEventListener(anyObject()); // we build a real DiffUtilComparator so we can generate realistic DiffUtil.DiffResult expect(delegate.createDiffUtilComparator()).andStubReturn(new DiffUtilComparator<ChildModel>() { @Override public boolean areItemsTheSame(ChildModel oldModel, ChildModel newModel) { return oldModel.key == newModel.key; } @Override public boolean areContentsTheSame(ChildModel oldModel, ChildModel newModel) { return oldModel.value.equals(newModel.value); } @Override public Object getChangePayload(ChildModel oldModel, ChildModel newModel) { return null; } }); return delegate; }
expect(delegates.get(0).createViewHolder(groupHolder.viewGroup)).andReturn(newChildViewHolders.get(1)).times(1); expect(delegates.get(0).createViewHolder(groupHolder.viewGroup)).andReturn(newChildViewHolders.get(3)).times(1); delegates.get(0).bindViewHolder(newChildViewHolders.get(1), newViewItems.get(1).model); delegates.get(0).bindViewHolder(newChildViewHolders.get(3), newViewItems.get(3).model);
delegates.get(0).unbindViewHolder(childViewHolders.get(0)); delegates.get(1).unbindViewHolder(childViewHolders.get(1)); delegates.get(0).unbindViewHolder(childViewHolders.get(2)); delegates.get(1).unbindViewHolder(childViewHolders.get(3)); delegates.get(0).bindViewHolder(childViewHolders.get(0), viewItems.get(0).model); delegates.get(1).bindViewHolder(childViewHolders.get(1), viewItems.get(1).model); delegates.get(0).bindViewHolder(childViewHolders.get(2), viewItems.get(2).model); delegates.get(1).bindViewHolder(childViewHolders.get(3), viewItems.get(3).model);
public void registerFeatureAnimatorListener(FeatureAnimatorListener featureAnimator, AdapterViewTypeDelegate viewTypeDelegate) { viewTypeFeatureAnimatorMap.put(viewTypeDelegate.getViewType(), featureAnimator); }
@Override public void onBindViewHolder(ViewHolder holder, int position) { final ViewItem item = featureItems.get(position); //noinspection unchecked mapViewTypeToAdapterViewTypeDelegate.get(item.viewType).bindViewHolder(holder, item.model); }