delegates refactored a bit
This commit is contained in:
commit
14ec33956f
|
|
@ -3,8 +3,6 @@ package ru.touchin.roboswag.components.adapters;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ru.touchin.roboswag.components.utils.LifecycleBindable;
|
||||
import ru.touchin.roboswag.components.utils.UiUtils;
|
||||
import rx.Completable;
|
||||
|
|
@ -18,12 +16,11 @@ import rx.functions.Action1;
|
|||
* Objects of such class controls creation and binding of specific type of RecyclerView's ViewHolders.
|
||||
* Default {@link #getItemViewType} is generating on construction of object.
|
||||
*
|
||||
* @param <TViewHolder> Type of {@link BindableViewHolder} of delegate;
|
||||
* @param <TItem> Type of items to bind to {@link BindableViewHolder}s.
|
||||
* @param <TViewHolder> Type of {@link BindableViewHolder} of delegate.
|
||||
*/
|
||||
@SuppressWarnings("PMD.TooManyMethods")
|
||||
//TooManyMethods: it's ok as it is LifecycleBindable
|
||||
public abstract class AdapterDelegate<TViewHolder extends BindableViewHolder, TItem> implements LifecycleBindable {
|
||||
//TooManyMethods: it's ok
|
||||
public abstract class AdapterDelegate<TViewHolder extends BindableViewHolder> implements LifecycleBindable {
|
||||
|
||||
@NonNull
|
||||
private final LifecycleBindable parentLifecycleBindable;
|
||||
|
|
@ -53,29 +50,6 @@ public abstract class AdapterDelegate<TViewHolder extends BindableViewHolder, TI
|
|||
return defaultItemViewType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if object is processable by this delegate.
|
||||
* This item will be casted to {@link TItem} and passes to {@link #onBindViewHolder(TViewHolder, TItem, int, int)}.
|
||||
*
|
||||
* @param item Item to check;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param itemCollectionPosition Position of item in collection that contains item;
|
||||
* @return True if item is processable by this delegate.
|
||||
*/
|
||||
public abstract boolean isForViewType(@NonNull final Object item, final int adapterPosition, final int itemCollectionPosition);
|
||||
|
||||
/**
|
||||
* Returns unique ID of item to support stable ID's logic of RecyclerView's adapter.
|
||||
*
|
||||
* @param item Item to check;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param itemCollectionPosition Position of item in collection that contains item;
|
||||
* @return Unique item ID.
|
||||
*/
|
||||
public long getItemId(@NonNull final TItem item, final int adapterPosition, final int itemCollectionPosition) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates ViewHolder to bind item to it later.
|
||||
*
|
||||
|
|
@ -85,31 +59,6 @@ public abstract class AdapterDelegate<TViewHolder extends BindableViewHolder, TI
|
|||
@NonNull
|
||||
public abstract TViewHolder onCreateViewHolder(@NonNull final ViewGroup parent);
|
||||
|
||||
/**
|
||||
* Binds item to created by this object ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind item to;
|
||||
* @param item Item to check;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param itemCollectionPosition Position of item in collection that contains item;
|
||||
*/
|
||||
public abstract void onBindViewHolder(@NonNull final TViewHolder holder, @NonNull final TItem item,
|
||||
final int adapterPosition, final int itemCollectionPosition);
|
||||
|
||||
/**
|
||||
* Binds item with payloads to created by this object ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind item to;
|
||||
* @param item Item to check;
|
||||
* @param payloads Payloads;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param itemCollectionPosition Position of item in collection that contains item;
|
||||
*/
|
||||
public void onBindViewHolder(@NonNull final TViewHolder holder, @NonNull final TItem item, @NonNull final List<Object> payloads,
|
||||
final int adapterPosition, final int itemCollectionPosition) {
|
||||
//do nothing by default
|
||||
}
|
||||
|
||||
@SuppressWarnings("CPD-START")
|
||||
//CPD: it is same as in other implementation based on BaseLifecycleBindable
|
||||
@NonNull
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
package ru.touchin.roboswag.components.adapters;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ru.touchin.roboswag.components.utils.LifecycleBindable;
|
||||
|
||||
/**
|
||||
* Objects of such class controls creation and binding of specific type of RecyclerView's ViewHolders.
|
||||
* Such delegates are creating and binding ViewHolders for specific items.
|
||||
* Default {@link #getItemViewType} is generating on construction of object.
|
||||
*
|
||||
* @param <TViewHolder> Type of {@link BindableViewHolder} of delegate;
|
||||
* @param <TItem> Type of items to bind to {@link BindableViewHolder}s.
|
||||
*/
|
||||
public abstract class ItemAdapterDelegate<TViewHolder extends BindableViewHolder, TItem> extends AdapterDelegate<TViewHolder> {
|
||||
|
||||
public ItemAdapterDelegate(@NonNull final LifecycleBindable parentLifecycleBindable) {
|
||||
super(parentLifecycleBindable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if object is processable by this delegate.
|
||||
* This item will be casted to {@link TItem} and passes to {@link #onBindViewHolder(TViewHolder, TItem, int, int)}.
|
||||
*
|
||||
* @param item Item to check;
|
||||
* @param positionInAdapter Position of item in adapter;
|
||||
* @param itemCollectionPosition Position of item in collection that contains item;
|
||||
* @return True if item is processable by this delegate.
|
||||
*/
|
||||
public abstract boolean isForViewType(@NonNull final Object item, final int positionInAdapter, final int itemCollectionPosition);
|
||||
|
||||
/**
|
||||
* Returns unique ID of item to support stable ID's logic of RecyclerView's adapter.
|
||||
*
|
||||
* @param item Item to check;
|
||||
* @param positionInAdapter Position of item in adapter;
|
||||
* @param positionInCollection Position of item in collection that contains item;
|
||||
* @return Unique item ID.
|
||||
*/
|
||||
public long getItemId(@NonNull final TItem item, final int positionInAdapter, final int positionInCollection) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates ViewHolder to bind item to it later.
|
||||
*
|
||||
* @param parent Container of ViewHolder's view.
|
||||
* @return New ViewHolder.
|
||||
*/
|
||||
@NonNull
|
||||
public abstract TViewHolder onCreateViewHolder(@NonNull final ViewGroup parent);
|
||||
|
||||
/**
|
||||
* Binds item to created by this object ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind item to;
|
||||
* @param item Item to check;
|
||||
* @param positionInAdapter Position of item in adapter;
|
||||
* @param positionInCollection Position of item in collection that contains item;
|
||||
*/
|
||||
public abstract void onBindViewHolder(@NonNull final TViewHolder holder, @NonNull final TItem item,
|
||||
final int positionInAdapter, final int positionInCollection);
|
||||
|
||||
/**
|
||||
* Binds item with payloads to created by this object ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind item to;
|
||||
* @param item Item to check;
|
||||
* @param payloads Payloads;
|
||||
* @param positionInAdapter Position of item in adapter;
|
||||
* @param positionInCollection Position of item in collection that contains item;
|
||||
*/
|
||||
public void onBindViewHolder(@NonNull final TViewHolder holder, @NonNull final TItem item, @NonNull final List<Object> payloads,
|
||||
final int positionInAdapter, final int positionInCollection) {
|
||||
//do nothing by default
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -42,6 +42,9 @@ import ru.touchin.roboswag.core.utils.Optional;
|
|||
import ru.touchin.roboswag.core.utils.ShouldNotHappenException;
|
||||
import rx.Observable;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.functions.Action1;
|
||||
import rx.functions.Action2;
|
||||
import rx.functions.Action3;
|
||||
import rx.subjects.BehaviorSubject;
|
||||
|
||||
/**
|
||||
|
|
@ -56,12 +59,22 @@ import rx.subjects.BehaviorSubject;
|
|||
* @param <TItem> Type of items to bind to ViewHolders;
|
||||
* @param <TItemViewHolder> Type of ViewHolders to show items.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({"unchecked", "PMD.TooManyMethods"})
|
||||
//TooManyMethods: it's ok
|
||||
public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends BindableViewHolder>
|
||||
extends RecyclerView.Adapter<BindableViewHolder> {
|
||||
|
||||
private static final int PRE_LOADING_COUNT = 20;
|
||||
|
||||
private static boolean inDebugMode;
|
||||
|
||||
/**
|
||||
* Enables debugging features like checking concurrent delegates.
|
||||
*/
|
||||
public static void setInDebugMode() {
|
||||
inDebugMode = true;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private final BehaviorSubject<Optional<ObservableCollection<TItem>>> observableCollectionSubject
|
||||
= BehaviorSubject.create(new Optional<>(null));
|
||||
|
|
@ -80,7 +93,7 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
@NonNull
|
||||
private final List<RecyclerView> attachedRecyclerViews = new LinkedList<>();
|
||||
@NonNull
|
||||
private final List<AdapterDelegate<TItemViewHolder, TItem>> delegates = new ArrayList<>();
|
||||
private final List<AdapterDelegate<? extends BindableViewHolder>> delegates = new ArrayList<>();
|
||||
|
||||
public ObservableCollectionAdapter(@NonNull final LifecycleBindable lifecycleBindable) {
|
||||
super();
|
||||
|
|
@ -301,23 +314,38 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
* @return List of {@link AdapterDelegate}.
|
||||
*/
|
||||
@NonNull
|
||||
public List<AdapterDelegate<TItemViewHolder, TItem>> getDelegates() {
|
||||
public List<AdapterDelegate<? extends BindableViewHolder>> getDelegates() {
|
||||
return Collections.unmodifiableList(delegates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@link AdapterDelegate} to adapter.
|
||||
* Adds {@link ItemAdapterDelegate} to adapter.
|
||||
*
|
||||
* @param delegate Delegate to add.
|
||||
*/
|
||||
public void addDelegate(@NonNull final AdapterDelegate<? extends TItemViewHolder, ? extends TItem> delegate) {
|
||||
for (final AdapterDelegate addedDelegate : delegates) {
|
||||
if (addedDelegate.getItemViewType() == delegate.getItemViewType()) {
|
||||
Lc.assertion("AdapterDelegate with viewType=" + delegate.getItemViewType() + " already added");
|
||||
return;
|
||||
public void addDelegate(@NonNull final ItemAdapterDelegate<? extends TItemViewHolder, ? extends TItem> delegate) {
|
||||
addDelegateInternal(delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@link PositionAdapterDelegate} to adapter.
|
||||
*
|
||||
* @param delegate Delegate to add.
|
||||
*/
|
||||
public void addDelegate(@NonNull final PositionAdapterDelegate<? extends BindableViewHolder> delegate) {
|
||||
addDelegateInternal(delegate);
|
||||
}
|
||||
|
||||
private void addDelegateInternal(@NonNull final AdapterDelegate<? extends BindableViewHolder> delegate) {
|
||||
if (inDebugMode) {
|
||||
for (final AdapterDelegate addedDelegate : delegates) {
|
||||
if (addedDelegate.getItemViewType() == delegate.getItemViewType()) {
|
||||
Lc.assertion("AdapterDelegate with viewType=" + delegate.getItemViewType() + " already added");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
delegates.add((AdapterDelegate<TItemViewHolder, TItem>) delegate);
|
||||
delegates.add(delegate);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
|
@ -326,41 +354,88 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
*
|
||||
* @param delegate Delegate to remove.
|
||||
*/
|
||||
public void removeDelegate(@NonNull final AdapterDelegate<? extends TItemViewHolder, ? extends TItem> delegate) {
|
||||
delegates.remove((AdapterDelegate<TItemViewHolder, TItem>) delegate);
|
||||
public void removeDelegate(@NonNull final AdapterDelegate<? extends BindableViewHolder> delegate) {
|
||||
delegates.remove(delegate);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void checkDelegates(@Nullable final AdapterDelegate alreadyPickedDelegate, @NonNull final AdapterDelegate currentDelegate) {
|
||||
if (alreadyPickedDelegate != null) {
|
||||
throw new ShouldNotHappenException("Concurrent delegates: " + currentDelegate + " and " + alreadyPickedDelegate);
|
||||
}
|
||||
}
|
||||
|
||||
private int getItemPositionInCollection(final int positionInAdapter) {
|
||||
final int shiftedPosition = positionInAdapter - getHeadersCount();
|
||||
return shiftedPosition >= 0 && shiftedPosition < innerCollection.size() ? shiftedPosition : -1;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ModifiedCyclomaticComplexity", "PMD.StdCyclomaticComplexity", "PMD.NPathComplexity"})
|
||||
//Complexity: because of debug code
|
||||
@Override
|
||||
public int getItemViewType(final int positionInAdapter) {
|
||||
final int positionInCollection = positionInAdapter - getHeadersCount();
|
||||
if (positionInCollection < 0 || positionInCollection >= innerCollection.size()) {
|
||||
return super.getItemViewType(positionInAdapter);
|
||||
}
|
||||
final TItem item = innerCollection.get(positionInCollection);
|
||||
for (final AdapterDelegate<?, TItem> delegate : delegates) {
|
||||
if (delegate.isForViewType(item, positionInAdapter, positionInCollection)) {
|
||||
return delegate.getItemViewType();
|
||||
AdapterDelegate delegateOfViewType = null;
|
||||
final int positionInCollection = getItemPositionInCollection(positionInAdapter);
|
||||
final TItem item = positionInCollection >= 0 ? innerCollection.get(positionInCollection) : null;
|
||||
for (final AdapterDelegate<?> delegate : delegates) {
|
||||
if (delegate instanceof ItemAdapterDelegate) {
|
||||
if (item != null && ((ItemAdapterDelegate) delegate).isForViewType(item, positionInAdapter, positionInCollection)) {
|
||||
checkDelegates(delegateOfViewType, delegate);
|
||||
delegateOfViewType = delegate;
|
||||
if (!inDebugMode) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (delegate instanceof PositionAdapterDelegate) {
|
||||
if (((PositionAdapterDelegate) delegate).isForViewType(positionInAdapter)) {
|
||||
checkDelegates(delegateOfViewType, delegate);
|
||||
delegateOfViewType = delegate;
|
||||
if (!inDebugMode) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Lc.assertion("Delegate of type " + delegate.getClass());
|
||||
}
|
||||
}
|
||||
return super.getItemViewType(positionInAdapter);
|
||||
|
||||
return delegateOfViewType != null ? delegateOfViewType.getItemViewType() : super.getItemViewType(positionInAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(final int positionInAdapter) {
|
||||
final int positionInCollection = positionInAdapter - getHeadersCount();
|
||||
if (positionInCollection < 0 || positionInCollection >= innerCollection.size()) {
|
||||
return super.getItemId(positionInAdapter);
|
||||
}
|
||||
final LongContainer result = new LongContainer();
|
||||
tryDelegateAction(positionInAdapter,
|
||||
(itemAdapterDelegate, item, positionInCollection) ->
|
||||
result.value = itemAdapterDelegate.getItemId(item, positionInAdapter, positionInCollection),
|
||||
positionAdapterDelegate -> result.value = positionAdapterDelegate.getItemId(positionInAdapter),
|
||||
(item, positionInCollection) -> result.value = super.getItemId(positionInAdapter));
|
||||
return result.value;
|
||||
}
|
||||
|
||||
final int itemViewType = getItemViewType(positionInAdapter);
|
||||
final TItem item = innerCollection.get(positionInCollection);
|
||||
for (final AdapterDelegate<?, TItem> delegate : delegates) {
|
||||
if (delegate.getItemViewType() == itemViewType) {
|
||||
return delegate.getItemId(item, positionInAdapter, positionInCollection);
|
||||
private void tryDelegateAction(final int positionInAdapter,
|
||||
@NonNull final Action3<ItemAdapterDelegate, TItem, Integer> itemAdapterDelegateAction,
|
||||
@NonNull final Action1<PositionAdapterDelegate> positionAdapterDelegateAction,
|
||||
@NonNull final Action2<TItem, Integer> defaultAction) {
|
||||
final int viewType = getItemViewType(positionInAdapter);
|
||||
final int positionInCollection = getItemPositionInCollection(positionInAdapter);
|
||||
final TItem item = positionInCollection >= 0 ? innerCollection.get(positionInCollection) : null;
|
||||
for (final AdapterDelegate<?> delegate : delegates) {
|
||||
if (delegate instanceof ItemAdapterDelegate) {
|
||||
if (item != null && viewType == delegate.getItemViewType()) {
|
||||
itemAdapterDelegateAction.call((ItemAdapterDelegate) delegate, item, positionInCollection);
|
||||
return;
|
||||
}
|
||||
} else if (delegate instanceof PositionAdapterDelegate) {
|
||||
if (viewType == delegate.getItemViewType()) {
|
||||
positionAdapterDelegateAction.call((PositionAdapterDelegate) delegate);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Lc.assertion("Delegate of type " + delegate.getClass());
|
||||
}
|
||||
}
|
||||
return super.getItemId(positionInAdapter);
|
||||
defaultAction.call(item, positionInCollection);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -371,7 +446,7 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
@NonNull
|
||||
@Override
|
||||
public BindableViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
|
||||
for (final AdapterDelegate<?, TItem> delegate : delegates) {
|
||||
for (final AdapterDelegate<?> delegate : delegates) {
|
||||
if (delegate.getItemViewType() == viewType) {
|
||||
return delegate.onCreateViewHolder(parent);
|
||||
}
|
||||
|
|
@ -383,26 +458,37 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
public void onBindViewHolder(@NonNull final BindableViewHolder holder, final int positionInAdapter) {
|
||||
lastUpdatedChangeNumber = innerCollection.getChangesCount();
|
||||
|
||||
final int positionInCollection = positionInAdapter - getHeadersCount();
|
||||
if (positionInCollection < 0 || positionInCollection >= innerCollection.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateMoreAutoLoadingRequest(positionInCollection);
|
||||
bindItemViewHolder(holder, null, positionInAdapter, positionInCollection);
|
||||
tryDelegateAction(positionInAdapter,
|
||||
(itemAdapterDelegate, item, positionInCollection) -> {
|
||||
bindItemViewHolder(itemAdapterDelegate, holder, item, null, positionInAdapter, positionInCollection);
|
||||
updateMoreAutoLoadingRequest(positionInCollection);
|
||||
},
|
||||
positionAdapterDelegate -> positionAdapterDelegate.onBindViewHolder(holder, positionInAdapter),
|
||||
(item, positionInCollection) -> {
|
||||
if (item != null) {
|
||||
bindItemViewHolder(null, holder, item, null, positionInAdapter, positionInCollection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final BindableViewHolder holder, final int positionInAdapter, @NonNull final List<Object> payloads) {
|
||||
super.onBindViewHolder(holder, positionInAdapter, payloads);
|
||||
final int positionInCollection = positionInAdapter - getHeadersCount();
|
||||
if (positionInCollection < 0 || positionInCollection >= innerCollection.size()) {
|
||||
return;
|
||||
}
|
||||
bindItemViewHolder(holder, payloads, positionInAdapter, positionInCollection);
|
||||
tryDelegateAction(positionInAdapter,
|
||||
(itemAdapterDelegate, item, positionInCollection) -> {
|
||||
bindItemViewHolder(itemAdapterDelegate, holder, item, payloads, positionInAdapter, positionInCollection);
|
||||
updateMoreAutoLoadingRequest(positionInCollection);
|
||||
},
|
||||
positionAdapterDelegate -> positionAdapterDelegate.onBindViewHolder(holder, positionInAdapter),
|
||||
(item, positionInCollection) -> {
|
||||
if (item != null) {
|
||||
bindItemViewHolder(null, holder, item, payloads, positionInAdapter, positionInCollection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void bindItemViewHolder(@NonNull final BindableViewHolder holder, @Nullable final List<Object> payloads,
|
||||
private void bindItemViewHolder(@Nullable final ItemAdapterDelegate<TItemViewHolder, TItem> itemAdapterDelegate,
|
||||
@NonNull final BindableViewHolder holder, @NonNull final TItem item, @Nullable final List<Object> payloads,
|
||||
final int positionInAdapter, final int positionInCollection) {
|
||||
final TItemViewHolder itemViewHolder;
|
||||
try {
|
||||
|
|
@ -411,24 +497,19 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
Lc.assertion(exception);
|
||||
return;
|
||||
}
|
||||
final TItem item = innerCollection.get(positionInCollection);
|
||||
final int itemViewType = getItemViewType(positionInAdapter);
|
||||
|
||||
updateClickListener(holder, item, positionInAdapter, positionInCollection);
|
||||
for (final AdapterDelegate<TItemViewHolder, TItem> delegate : delegates) {
|
||||
if (itemViewType == delegate.getItemViewType()) {
|
||||
if (payloads == null) {
|
||||
delegate.onBindViewHolder(itemViewHolder, item, positionInAdapter, positionInCollection);
|
||||
} else {
|
||||
delegate.onBindViewHolder(itemViewHolder, item, payloads, positionInAdapter, positionInCollection);
|
||||
}
|
||||
return;
|
||||
if (itemAdapterDelegate != null) {
|
||||
if (payloads == null) {
|
||||
itemAdapterDelegate.onBindViewHolder(itemViewHolder, item, positionInAdapter, positionInCollection);
|
||||
} else {
|
||||
itemAdapterDelegate.onBindViewHolder(itemViewHolder, item, payloads, positionInAdapter, positionInCollection);
|
||||
}
|
||||
}
|
||||
if (payloads == null) {
|
||||
onBindItemToViewHolder(itemViewHolder, positionInAdapter, item);
|
||||
} else {
|
||||
onBindItemToViewHolder(itemViewHolder, positionInAdapter, item, payloads);
|
||||
if (payloads == null) {
|
||||
onBindItemToViewHolder(itemViewHolder, positionInAdapter, item);
|
||||
} else {
|
||||
onBindItemToViewHolder(itemViewHolder, positionInAdapter, item, payloads);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -485,8 +566,8 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
|
||||
@Nullable
|
||||
public TItem getItem(final int positionInAdapter) {
|
||||
final int positionInCollection = positionInAdapter - getHeadersCount();
|
||||
return positionInCollection < 0 || positionInCollection >= innerCollection.size() ? null : innerCollection.get(positionInCollection);
|
||||
final int positionInCollection = getItemPositionInCollection(positionInAdapter);
|
||||
return positionInCollection >= 0 ? innerCollection.get(positionInCollection) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -577,4 +658,10 @@ public abstract class ObservableCollectionAdapter<TItem, TItemViewHolder extends
|
|||
|
||||
}
|
||||
|
||||
private class LongContainer {
|
||||
|
||||
private long value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
package ru.touchin.roboswag.components.adapters;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ru.touchin.roboswag.components.utils.LifecycleBindable;
|
||||
|
||||
/**
|
||||
* Objects of such class controls creation and binding of specific type of RecyclerView's ViewHolders.
|
||||
* Such delegates are creating and binding ViewHolders by position in adapter.
|
||||
* Default {@link #getItemViewType} is generating on construction of object.
|
||||
*
|
||||
* @param <TViewHolder> Type of {@link BindableViewHolder} of delegate.
|
||||
*/
|
||||
public abstract class PositionAdapterDelegate<TViewHolder extends BindableViewHolder> extends AdapterDelegate<TViewHolder> {
|
||||
|
||||
public PositionAdapterDelegate(@NonNull final LifecycleBindable parentLifecycleBindable) {
|
||||
super(parentLifecycleBindable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if object is processable by this delegate.
|
||||
*
|
||||
* @param positionInAdapter Position of item in adapter;
|
||||
* @return True if item is processable by this delegate.
|
||||
*/
|
||||
public abstract boolean isForViewType(final int positionInAdapter);
|
||||
|
||||
/**
|
||||
* Returns unique ID of item to support stable ID's logic of RecyclerView's adapter.
|
||||
*
|
||||
* @param positionInAdapter Position of item in adapter;
|
||||
* @return Unique item ID.
|
||||
*/
|
||||
public long getItemId(final int positionInAdapter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates ViewHolder to bind position to it later.
|
||||
*
|
||||
* @param parent Container of ViewHolder's view.
|
||||
* @return New ViewHolder.
|
||||
*/
|
||||
@NonNull
|
||||
public abstract TViewHolder onCreateViewHolder(@NonNull final ViewGroup parent);
|
||||
|
||||
/**
|
||||
* Binds position to ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind position to;
|
||||
* @param positionInAdapter Position of item in adapter.
|
||||
*/
|
||||
public abstract void onBindViewHolder(@NonNull final TViewHolder holder, final int positionInAdapter);
|
||||
|
||||
/**
|
||||
* Binds position with payloads to ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind position to;
|
||||
* @param payloads Payloads;
|
||||
* @param positionInAdapter Position of item in adapter.
|
||||
*/
|
||||
public void onBindViewHolder(@NonNull final TViewHolder holder, @NonNull final List<Object> payloads, final int positionInAdapter) {
|
||||
//do nothing by default
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue