From 6d98007ffa4e1f9f66f047552f2f059d6a651c96 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sat, 15 Jul 2017 22:48:43 +0200 Subject: [PATCH 1/4] * implement new ModelAdapter, base ItemAdapter on modelAdapter * adjust all methods and add additional internal methods (which need to be implemented in the IItemAdapter) --- .../mikepenz/fastadapter/IInterceptor.java | 8 + .../mikepenz/fastadapter/IItemAdapter.java | 45 +- .../fastadapter/adapters/ItemAdapter.java | 443 +--------------- .../fastadapter/adapters/ItemFilter.java | 36 +- .../fastadapter/adapters/ModelAdapter.java | 500 ++++++++++++++++++ .../fastadapter/items/AbstractItem.java | 1 + .../expandable/ExpandableExtension.java | 2 +- .../fastadapter_extensions/UndoHelper.java | 12 +- .../scroll/EndlessScrollHelper.java | 14 +- .../commons/adapters/FastItemAdapter.java | 2 +- 10 files changed, 589 insertions(+), 474 deletions(-) create mode 100644 library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java create mode 100644 library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java b/library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java new file mode 100644 index 000000000..4e563eef6 --- /dev/null +++ b/library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java @@ -0,0 +1,8 @@ +package com.mikepenz.fastadapter; + +/** + * Created by mikepenz on 30.12.15. + */ +public interface IInterceptor { + Item intercept(Element element); +} diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/IItemAdapter.java b/library-core/src/main/java/com/mikepenz/fastadapter/IItemAdapter.java index 83a2c229b..00f4548f8 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/IItemAdapter.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/IItemAdapter.java @@ -5,35 +5,42 @@ /** * Created by mikepenz on 30.12.15. */ -public interface IItemAdapter extends IAdapter { +public interface IItemAdapter extends IAdapter { /** * set a new list of items and apply it to the existing list (clear - add) for this adapter * * @param items */ - IItemAdapter set(List items); + IItemAdapter set(List items); /** * sets a complete new list of items onto this adapter, using the new list. Calls notifyDataSetChanged * * @param items */ - IItemAdapter setNewList(List items); + IItemAdapter setNewList(List items); /** * add an array of items to the end of the existing items * * @param items */ - IItemAdapter add(Item... items); + IItemAdapter add(Model... items); /** * add a list of items to the end of the existing items * * @param items */ - IItemAdapter add(List items); + IItemAdapter add(List items); + + /** + * add a list of items to the end of the existing items + * + * @param items + */ + IItemAdapter addInternal(List items); /** * add an array of items at the given position within the existing items @@ -41,7 +48,15 @@ public interface IItemAdapter extends IAdapter { * @param position the global position * @param items */ - IItemAdapter add(int position, Item... items); + IItemAdapter add(int position, Model... items); + + /** + * add a list of items at the given position within the existing items + * + * @param position the global position + * @param items + */ + IItemAdapter add(int position, List items); /** * add a list of items at the given position within the existing items @@ -49,7 +64,15 @@ public interface IItemAdapter extends IAdapter { * @param position the global position * @param items */ - IItemAdapter add(int position, List items); + IItemAdapter addInternal(int position, List items); + + /** + * sets an item at the given position, overwriting the previous item + * + * @param position the global position + * @param item + */ + IItemAdapter set(int position, Model item); /** * sets an item at the given position, overwriting the previous item @@ -57,14 +80,14 @@ public interface IItemAdapter extends IAdapter { * @param position the global position * @param item */ - IItemAdapter set(int position, Item item); + IItemAdapter setInternal(int position, Item item); /** * removes an item at the given position within the existing icons * * @param position the global position */ - IItemAdapter remove(int position); + IItemAdapter remove(int position); /** * removes a range of items starting with the given position within the existing icons @@ -72,12 +95,12 @@ public interface IItemAdapter extends IAdapter { * @param position the global position * @param itemCount */ - IItemAdapter removeRange(int position, int itemCount); + IItemAdapter removeRange(int position, int itemCount); /** * removes all items of this adapter */ - IItemAdapter clear(); + IItemAdapter clear(); /** * the interface used to filter the list inside the ItemFilter diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java index 8f973d565..531957314 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java @@ -1,28 +1,22 @@ package com.mikepenz.fastadapter.adapters; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.mikepenz.fastadapter.AbstractAdapter; -import com.mikepenz.fastadapter.IAdapterExtension; +import com.mikepenz.fastadapter.IInterceptor; import com.mikepenz.fastadapter.IItem; -import com.mikepenz.fastadapter.IItemAdapter; -import com.mikepenz.fastadapter.utils.IdDistributor; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import static java.util.Arrays.asList; /** * Created by mikepenz on 27.12.15. * A general ItemAdapter implementation based on the AbstractAdapter to speed up development for general items */ -public class ItemAdapter extends AbstractAdapter implements IItemAdapter { - //the items handled and managed by this item - private List mItems = new ArrayList<>(); +public class ItemAdapter extends ModelAdapter { + + public ItemAdapter() { + super(new IInterceptor() { + @Override + public Item intercept(Item item) { + return item; + } + }); + } /** * static method to retrieve a new `ItemAdapter` @@ -32,419 +26,4 @@ public class ItemAdapter extends AbstractAdapter imple public static ItemAdapter items() { return new ItemAdapter<>(); } - - //defines if the IdDistributor is used to set ID's to all added items - private boolean mUseIdDistributor = true; - - /** - * defines if the IdDistributor is used to provide an ID to all added items which do not yet define an id - * - * @param useIdDistributor false if the IdDistributor shouldn't be used - * @return this - */ - public ItemAdapter withUseIdDistributor(boolean useIdDistributor) { - this.mUseIdDistributor = useIdDistributor; - return this; - } - - /** - * @return if we use the idDistributor with this adapter - */ - public boolean isUseIdDistributor() { - return mUseIdDistributor; - } - - //filters the items - private ItemFilter mItemFilter = new ItemFilter<>(this); - - /** - * allows you to define your own Filter implementation instead of the default `ItemFilter` - * - * @param itemFilter the filter to use - * @return this - */ - public ItemAdapter withItemFilter(@NonNull ItemFilter itemFilter) { - this.mItemFilter = itemFilter; - return this; - } - - /** - * @return the filter used to filter items - */ - @NonNull - public ItemFilter getItemFilter() { - return mItemFilter; - } - - /** - * filters the items with the constraint using the provided Predicate - * - * @param constraint the string used to filter the list - */ - public void filter(@Nullable CharSequence constraint) { - mItemFilter.filter(constraint); - } - - // - protected Comparator mComparator; - - /** - * define a comparator which will be used to sort the list "everytime" it is altered - * NOTE this will only sort if you "set" a new list or "add" new items (not if you provide a position for the add function) - * - * @param comparator used to sort the list - * @return this - */ - public ItemAdapter withComparator(Comparator comparator) { - return withComparator(comparator, true); - } - - /** - * define a comparator which will be used to sort the list "everytime" it is altered - * NOTE this will only sort if you "set" a new list or "add" new items (not if you provide a position for the add function) - * - * @param comparator used to sort the list - * @param sortNow specifies if we use the provided comparator to sort now - * @return this - */ - public ItemAdapter withComparator(Comparator comparator, boolean sortNow) { - this.mComparator = comparator; - - //we directly sort the list with the defined comparator - if (mItems != null && mComparator != null && sortNow) { - Collections.sort(mItems, mComparator); - getFastAdapter().notifyAdapterDataSetChanged(); - } - - return this; - } - - - /** - * @return the defined Comparator used for this ItemAdaper - */ - public Comparator getComparator() { - return mComparator; - } - - /** - * @return the count of items within this adapter - */ - @Override - public int getAdapterItemCount() { - return mItems.size(); - } - - /** - * @return the items within this adapter - */ - @Override - public List getAdapterItems() { - return mItems; - } - - /** - * Searches for the given item and calculates its relative position - * - * @param item the item which is searched for - * @return the relative position - */ - @Override - public int getAdapterPosition(Item item) { - return getAdapterPosition(item.getIdentifier()); - } - - /** - * Searches for the given identifier and calculates its relative position - * - * @param identifier the identifier of an item which is searched for - * @return the relative position - */ - @Override - public int getAdapterPosition(long identifier) { - for (int i = 0, size = mItems.size(); i < size; i++) { - if (mItems.get(i).getIdentifier() == identifier) { - return i; - } - } - return -1; - } - - /** - * returns the global position if the relative position within this adapter was given - * - * @param position the relative position - * @return the global position - */ - public int getGlobalPosition(int position) { - return position + getFastAdapter().getPreItemCountByOrder(getOrder()); - } - - /** - * @param position the relative position - * @return the item inside this adapter - */ - @Override - public Item getAdapterItem(int position) { - return mItems.get(position); - } - - /** - * set a new list of items and apply it to the existing list (clear - add) for this adapter - * NOTE may consider using setNewList if the items list is a reference to the list which is used inside the adapter - * NOTE this will not sort - * - * @param items the items to set - */ - public ItemAdapter set(List items) { - return set(items, true); - } - - protected ItemAdapter set(List items, boolean resetFilter) { - if (mUseIdDistributor) { - IdDistributor.checkIds(items); - } - - //reset the filter - if (resetFilter && getItemFilter().getConstraint() != null) { - getItemFilter().performFiltering(null); - } - - for (IAdapterExtension ext : getFastAdapter().getExtensions()) { - ext.set(items, resetFilter); - } - - //get sizes - int newItemsCount = items.size(); - int previousItemsCount = mItems.size(); - int itemsBeforeThisAdapter = getFastAdapter().getPreItemCountByOrder(getOrder()); - - //make sure the new items list is not a reference of the already mItems list - if (items != mItems) { - //remove all previous items - if (!mItems.isEmpty()) { - mItems.clear(); - } - - //add all new items to the list - mItems.addAll(items); - } - - //map the types - mapPossibleTypes(items); - - //if we have a comparator then sort - if (mComparator != null) { - Collections.sort(mItems, mComparator); - } - - //now properly notify the adapter about the changes - if (newItemsCount > previousItemsCount) { - if (previousItemsCount > 0) { - getFastAdapter().notifyAdapterItemRangeChanged(itemsBeforeThisAdapter, previousItemsCount); - } - getFastAdapter().notifyAdapterItemRangeInserted(itemsBeforeThisAdapter + previousItemsCount, newItemsCount - previousItemsCount); - } else if (newItemsCount > 0) { - getFastAdapter().notifyAdapterItemRangeChanged(itemsBeforeThisAdapter, newItemsCount); - if (newItemsCount < previousItemsCount) { - getFastAdapter().notifyAdapterItemRangeRemoved(itemsBeforeThisAdapter + newItemsCount, previousItemsCount - newItemsCount); - } - } else if (newItemsCount == 0) { - getFastAdapter().notifyAdapterItemRangeRemoved(itemsBeforeThisAdapter, previousItemsCount); - } else { - //this condition should practically never happen - getFastAdapter().notifyAdapterDataSetChanged(); - } - - return this; - } - - /** - * sets a complete new list of items onto this adapter, using the new list. Calls notifyDataSetChanged - * - * @param items the new items to set - */ - public ItemAdapter setNewList(List items) { - return setNewList(items, false); - } - - /** - * sets a complete new list of items onto this adapter, using the new list. Calls notifyDataSetChanged - * - * @param items the new items to set - * @param retainFilter set to true if you want to keep the filter applied - * @return this - */ - public ItemAdapter setNewList(List items, boolean retainFilter) { - if (mUseIdDistributor) { - IdDistributor.checkIds(items); - } - - //reset the filter - CharSequence filter = null; - if (getItemFilter().getConstraint() != null) { - filter = getItemFilter().getConstraint(); - getItemFilter().performFiltering(null); - } - - mItems = new ArrayList<>(items); - mapPossibleTypes(mItems); - - if (mComparator != null) { - Collections.sort(mItems, mComparator); - } - - if (filter != null && retainFilter) { - getItemFilter().publishResults(filter, getItemFilter().performFiltering(filter)); - } else { - getFastAdapter().notifyAdapterDataSetChanged(); - } - - return this; - } - - /** - * forces to remap all possible types for the RecyclerView - */ - public void remapMappedTypes() { - getFastAdapter().clearTypeInstance(); - mapPossibleTypes(mItems); - } - - /** - * add an array of items to the end of the existing items - * - * @param items the items to add - */ - @SafeVarargs - public final ItemAdapter add(Item... items) { - return add(asList(items)); - } - - /** - * add a list of items to the end of the existing items - * - * @param items the items to add - */ - public ItemAdapter add(List items) { - if (mUseIdDistributor) { - IdDistributor.checkIds(items); - } - int countBefore = mItems.size(); - mItems.addAll(items); - mapPossibleTypes(items); - - if (mComparator == null) { - getFastAdapter().notifyAdapterItemRangeInserted(getFastAdapter().getPreItemCountByOrder(getOrder()) + countBefore, items.size()); - } else { - Collections.sort(mItems, mComparator); - getFastAdapter().notifyAdapterDataSetChanged(); - } - return this; - } - - /** - * add an array of items at the given position within the existing items - * - * @param position the global position - * @param items the items to add - */ - @SafeVarargs - public final ItemAdapter add(int position, Item... items) { - return add(position, asList(items)); - } - - /** - * add a list of items at the given position within the existing items - * - * @param position the global position - * @param items the items to add - */ - public ItemAdapter add(int position, List items) { - if (mUseIdDistributor) { - IdDistributor.checkIds(items); - } - if (items != null && items.size() > 0) { - mItems.addAll(position - getFastAdapter().getPreItemCountByOrder(getOrder()), items); - mapPossibleTypes(items); - - getFastAdapter().notifyAdapterItemRangeInserted(position, items.size()); - } - return this; - } - - /** - * sets an item at the given position, overwriting the previous item - * - * @param position the global position - * @param item the item to set - */ - public ItemAdapter set(int position, Item item) { - if (mUseIdDistributor) { - IdDistributor.checkId(item); - } - mItems.set(position - getFastAdapter().getPreItemCount(position), item); - mFastAdapter.registerTypeInstance(item); - - getFastAdapter().notifyAdapterItemChanged(position); - return this; - } - - /** - * moves an item within the list from a position to a position - * - * @param fromPosition the position global from which we want to move - * @param toPosition the global position to which to move - * @return this - */ - public ItemAdapter move(int fromPosition, int toPosition) { - int preItemCount = getFastAdapter().getPreItemCount(fromPosition); - Item item = mItems.get(fromPosition - preItemCount); - mItems.remove(fromPosition - preItemCount); - mItems.add(toPosition - preItemCount, item); - getFastAdapter().notifyAdapterItemMoved(fromPosition, toPosition); - return this; - } - - /** - * removes an item at the given position within the existing icons - * - * @param position the global position - */ - public ItemAdapter remove(int position) { - mItems.remove(position - getFastAdapter().getPreItemCount(position)); - getFastAdapter().notifyAdapterItemRemoved(position); - return this; - } - - /** - * removes a range of items starting with the given position within the existing icons - * - * @param position the global position - * @param itemCount the count of items which were removed - */ - public ItemAdapter removeRange(int position, int itemCount) { - //global position to relative - int length = mItems.size(); - int preItemCount = getFastAdapter().getPreItemCount(position); - //make sure we do not delete to many items - int saveItemCount = Math.min(itemCount, length - position + preItemCount); - - for (int i = 0; i < saveItemCount; i++) { - mItems.remove(position - preItemCount); - } - - getFastAdapter().notifyAdapterItemRangeRemoved(position, saveItemCount); - return this; - } - - /** - * removes all items of this adapter - */ - public ItemAdapter clear() { - int count = mItems.size(); - mItems.clear(); - getFastAdapter().notifyAdapterItemRangeRemoved(getFastAdapter().getPreItemCountByOrder(getOrder()), count); - return this; - } } diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java index d96ae6d60..91ec6a5e8 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java @@ -19,12 +19,12 @@ * ItemFilter which extends the Filter api provided by Android * This calls automatically all required methods, just overwrite the filterItems method */ -public class ItemFilter extends Filter { +public class ItemFilter extends Filter { private List mOriginalItems; private CharSequence mConstraint; - private ItemAdapter mItemAdapter; + private ModelAdapter mItemAdapter; - public ItemFilter(ItemAdapter itemAdapter) { + public ItemFilter(ModelAdapter itemAdapter) { this.mItemAdapter = itemAdapter; } @@ -36,7 +36,7 @@ public ItemFilter(ItemAdapter itemAdapter) { * @param listener which will be called after the items were filtered * @return this */ - public ItemFilter withItemFilterListener(ItemFilterListener listener) { + public ItemFilter withItemFilterListener(ItemFilterListener listener) { mItemFilterListener = listener; return this; } @@ -50,7 +50,7 @@ public ItemFilter withItemFilterListener(ItemFilterListener listener * @param filterPredicate the predicate used to filter the list inside the ItemFilter * @return this */ - public ItemFilter withFilterPredicate(IItemAdapter.Predicate filterPredicate) { + public ItemFilter withFilterPredicate(IItemAdapter.Predicate filterPredicate) { this.mFilterPredicate = filterPredicate; return this; } @@ -114,7 +114,7 @@ public CharSequence getConstraint() { protected void publishResults(CharSequence constraint, FilterResults results) { // Now we have to inform the adapter about the new list filtered if (results.values != null) { - mItemAdapter.set((List) results.values, false); + mItemAdapter.setInternal((List) results.values, false); } if (mItemFilterListener != null) { @@ -194,7 +194,7 @@ public int getAdapterPosition(long identifier) { * @param items the items to add */ @SafeVarargs - public final ItemAdapter add(Item... items) { + public final ModelAdapter add(Item... items) { return add(asList(items)); } @@ -204,7 +204,7 @@ public final ItemAdapter add(Item... items) { * * @param items the items to add */ - public ItemAdapter add(List items) { + public ModelAdapter add(List items) { if (mOriginalItems != null && items.size() > 0) { if (mItemAdapter.isUseIdDistributor()) { IdDistributor.checkIds(items); @@ -213,7 +213,7 @@ public ItemAdapter add(List items) { publishResults(mConstraint, performFiltering(mConstraint)); return mItemAdapter; } else { - return mItemAdapter.add(items); + return mItemAdapter.addInternal(items); } } @@ -224,7 +224,7 @@ public ItemAdapter add(List items) { * @param items the items to add */ @SafeVarargs - public final ItemAdapter add(int position, Item... items) { + public final ModelAdapter add(int position, Item... items) { return add(position, asList(items)); } @@ -234,7 +234,7 @@ public final ItemAdapter add(int position, Item... items) { * @param position the global position * @param items the items to add */ - public ItemAdapter add(int position, List items) { + public ModelAdapter add(int position, List items) { if (mOriginalItems != null && items.size() > 0) { if (mItemAdapter.isUseIdDistributor()) { IdDistributor.checkIds(items); @@ -243,7 +243,7 @@ public ItemAdapter add(int position, List items) { publishResults(mConstraint, performFiltering(mConstraint)); return mItemAdapter; } else { - return mItemAdapter.add(position, items); + return mItemAdapter.addInternal(position, items); } } @@ -253,7 +253,7 @@ public ItemAdapter add(int position, List items) { * @param position the global position * @param item the item to set */ - public ItemAdapter set(int position, Item item) { + public ModelAdapter set(int position, Item item) { if (mOriginalItems != null) { if (mItemAdapter.isUseIdDistributor()) { IdDistributor.checkId(item); @@ -262,7 +262,7 @@ public ItemAdapter set(int position, Item item) { publishResults(mConstraint, performFiltering(mConstraint)); return mItemAdapter; } else { - return mItemAdapter.set(position, item); + return mItemAdapter.setInternal(position, item); } } @@ -273,7 +273,7 @@ public ItemAdapter set(int position, Item item) { * @param toPosition the global position to which to move * @return this */ - public ItemAdapter move(int fromPosition, int toPosition) { + public ModelAdapter move(int fromPosition, int toPosition) { if (mOriginalItems != null) { int preItemCount = mItemAdapter.getFastAdapter().getPreItemCount(fromPosition); int adjustedFrom = getAdapterPosition(mItemAdapter.getAdapterItems().get(fromPosition)); @@ -293,7 +293,7 @@ public ItemAdapter move(int fromPosition, int toPosition) { * * @param position the global position */ - public ItemAdapter remove(int position) { + public ModelAdapter remove(int position) { if (mOriginalItems != null) { mOriginalItems.remove(getAdapterPosition(mItemAdapter.getAdapterItems().get(position)) - mItemAdapter.getFastAdapter().getPreItemCount(position)); publishResults(mConstraint, performFiltering(mConstraint)); @@ -309,7 +309,7 @@ public ItemAdapter remove(int position) { * @param position the global position * @param itemCount the count of items which were removed */ - public ItemAdapter removeRange(int position, int itemCount) { + public ModelAdapter removeRange(int position, int itemCount) { if (mOriginalItems != null) { //global position to relative int length = mOriginalItems.size(); @@ -329,7 +329,7 @@ public ItemAdapter removeRange(int position, int itemCount) { /** * removes all items of this adapter */ - public ItemAdapter clear() { + public ModelAdapter clear() { if (mOriginalItems != null) { mOriginalItems.clear(); publishResults(mConstraint, performFiltering(mConstraint)); diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java new file mode 100644 index 000000000..22bb5b845 --- /dev/null +++ b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java @@ -0,0 +1,500 @@ +package com.mikepenz.fastadapter.adapters; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.mikepenz.fastadapter.AbstractAdapter; +import com.mikepenz.fastadapter.IAdapterExtension; +import com.mikepenz.fastadapter.IInterceptor; +import com.mikepenz.fastadapter.IItem; +import com.mikepenz.fastadapter.IItemAdapter; +import com.mikepenz.fastadapter.utils.IdDistributor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created by mikepenz on 27.12.15. + * A general ItemAdapter implementation based on the AbstractAdapter to speed up development for general items + */ +public class ModelAdapter extends AbstractAdapter implements IItemAdapter { + //the items handled and managed by this item + private List mItems = new ArrayList<>(); + + public ModelAdapter(IInterceptor interceptor) { + this.mInterceptor = interceptor; + } + + /** + * static method to retrieve a new `ItemAdapter` + * + * @return a new ItemAdapter + */ + public static ModelAdapter models(IInterceptor interceptor) { + return new ModelAdapter<>(interceptor); + } + + private IInterceptor mInterceptor; + + public IInterceptor getInterceptor() { + return mInterceptor; + } + + public ModelAdapter withInterceptor(IInterceptor mInterceptor) { + this.mInterceptor = mInterceptor; + return this; + } + + private Item intercept(Model model) { + return mInterceptor.intercept(model); + } + + private List intercept(List models) { + List items = new ArrayList<>(models.size()); + for (Model model : models) { + items.add(intercept(model)); + } + return items; + } + + //defines if the IdDistributor is used to set ID's to all added items + private boolean mUseIdDistributor = true; + + /** + * defines if the IdDistributor is used to provide an ID to all added items which do not yet define an id + * + * @param useIdDistributor false if the IdDistributor shouldn't be used + * @return this + */ + public ModelAdapter withUseIdDistributor(boolean useIdDistributor) { + this.mUseIdDistributor = useIdDistributor; + return this; + } + + /** + * @return if we use the idDistributor with this adapter + */ + public boolean isUseIdDistributor() { + return mUseIdDistributor; + } + + //filters the items + private ItemFilter mItemFilter = new ItemFilter<>(this); + + /** + * allows you to define your own Filter implementation instead of the default `ItemFilter` + * + * @param itemFilter the filter to use + * @return this + */ + public ModelAdapter withItemFilter(@NonNull ItemFilter itemFilter) { + this.mItemFilter = itemFilter; + return this; + } + + /** + * @return the filter used to filter items + */ + @NonNull + public ItemFilter getItemFilter() { + return mItemFilter; + } + + /** + * filters the items with the constraint using the provided Predicate + * + * @param constraint the string used to filter the list + */ + public void filter(@Nullable CharSequence constraint) { + mItemFilter.filter(constraint); + } + + // + protected Comparator mComparator; + + /** + * define a comparator which will be used to sort the list "everytime" it is altered + * NOTE this will only sort if you "set" a new list or "add" new items (not if you provide a position for the add function) + * + * @param comparator used to sort the list + * @return this + */ + public ModelAdapter withComparator(Comparator comparator) { + return withComparator(comparator, true); + } + + /** + * define a comparator which will be used to sort the list "everytime" it is altered + * NOTE this will only sort if you "set" a new list or "add" new items (not if you provide a position for the add function) + * + * @param comparator used to sort the list + * @param sortNow specifies if we use the provided comparator to sort now + * @return this + */ + public ModelAdapter withComparator(Comparator comparator, boolean sortNow) { + this.mComparator = comparator; + + //we directly sort the list with the defined comparator + if (mItems != null && mComparator != null && sortNow) { + Collections.sort(mItems, mComparator); + getFastAdapter().notifyAdapterDataSetChanged(); + } + + return this; + } + + + /** + * @return the defined Comparator used for this ItemAdaper + */ + public Comparator getComparator() { + return mComparator; + } + + /** + * @return the count of items within this adapter + */ + @Override + public int getAdapterItemCount() { + return mItems.size(); + } + + /** + * @return the items within this adapter + */ + @Override + public List getAdapterItems() { + return mItems; + } + + /** + * Searches for the given item and calculates its relative position + * + * @param item the item which is searched for + * @return the relative position + */ + @Override + public int getAdapterPosition(Item item) { + return getAdapterPosition(item.getIdentifier()); + } + + /** + * Searches for the given identifier and calculates its relative position + * + * @param identifier the identifier of an item which is searched for + * @return the relative position + */ + @Override + public int getAdapterPosition(long identifier) { + for (int i = 0, size = mItems.size(); i < size; i++) { + if (mItems.get(i).getIdentifier() == identifier) { + return i; + } + } + return -1; + } + + /** + * returns the global position if the relative position within this adapter was given + * + * @param position the relative position + * @return the global position + */ + public int getGlobalPosition(int position) { + return position + getFastAdapter().getPreItemCountByOrder(getOrder()); + } + + /** + * @param position the relative position + * @return the item inside this adapter + */ + @Override + public Item getAdapterItem(int position) { + return mItems.get(position); + } + + /** + * set a new list of items and apply it to the existing list (clear - add) for this adapter + * NOTE may consider using setNewList if the items list is a reference to the list which is used inside the adapter + * NOTE this will not sort + * + * @param items the items to set + */ + public ModelAdapter set(List items) { + return set(items, true); + } + + protected ModelAdapter set(List list, boolean resetFilter) { + List items = intercept(list); + return setInternal(items, resetFilter); + } + + public ModelAdapter setInternal(List items, boolean resetFilter) { + if (mUseIdDistributor) { + IdDistributor.checkIds(items); + } + + //reset the filter + if (resetFilter && getItemFilter().getConstraint() != null) { + getItemFilter().performFiltering(null); + } + + for (IAdapterExtension ext : getFastAdapter().getExtensions()) { + ext.set(items, resetFilter); + } + + //get sizes + int newItemsCount = items.size(); + int previousItemsCount = mItems.size(); + int itemsBeforeThisAdapter = getFastAdapter().getPreItemCountByOrder(getOrder()); + + //make sure the new items list is not a reference of the already mItems list + if (items != mItems) { + //remove all previous items + if (!mItems.isEmpty()) { + mItems.clear(); + } + + //add all new items to the list + mItems.addAll(items); + } + + //map the types + mapPossibleTypes(items); + + //if we have a comparator then sort + if (mComparator != null) { + Collections.sort(mItems, mComparator); + } + + //now properly notify the adapter about the changes + if (newItemsCount > previousItemsCount) { + if (previousItemsCount > 0) { + getFastAdapter().notifyAdapterItemRangeChanged(itemsBeforeThisAdapter, previousItemsCount); + } + getFastAdapter().notifyAdapterItemRangeInserted(itemsBeforeThisAdapter + previousItemsCount, newItemsCount - previousItemsCount); + } else if (newItemsCount > 0) { + getFastAdapter().notifyAdapterItemRangeChanged(itemsBeforeThisAdapter, newItemsCount); + if (newItemsCount < previousItemsCount) { + getFastAdapter().notifyAdapterItemRangeRemoved(itemsBeforeThisAdapter + newItemsCount, previousItemsCount - newItemsCount); + } + } else if (newItemsCount == 0) { + getFastAdapter().notifyAdapterItemRangeRemoved(itemsBeforeThisAdapter, previousItemsCount); + } else { + //this condition should practically never happen + getFastAdapter().notifyAdapterDataSetChanged(); + } + + return this; + } + + /** + * sets a complete new list of items onto this adapter, using the new list. Calls notifyDataSetChanged + * + * @param items the new items to set + */ + public ModelAdapter setNewList(List items) { + return setNewList(items, false); + } + + /** + * sets a complete new list of items onto this adapter, using the new list. Calls notifyDataSetChanged + * + * @param list the new items to set + * @param retainFilter set to true if you want to keep the filter applied + * @return this + */ + public ModelAdapter setNewList(List list, boolean retainFilter) { + List items = intercept(list); + + if (mUseIdDistributor) { + IdDistributor.checkIds(items); + } + + //reset the filter + CharSequence filter = null; + if (getItemFilter().getConstraint() != null) { + filter = getItemFilter().getConstraint(); + getItemFilter().performFiltering(null); + } + + mItems = new ArrayList<>(items); + mapPossibleTypes(mItems); + + if (mComparator != null) { + Collections.sort(mItems, mComparator); + } + + if (filter != null && retainFilter) { + getItemFilter().publishResults(filter, getItemFilter().performFiltering(filter)); + } else { + getFastAdapter().notifyAdapterDataSetChanged(); + } + + return this; + } + + /** + * forces to remap all possible types for the RecyclerView + */ + public void remapMappedTypes() { + getFastAdapter().clearTypeInstance(); + mapPossibleTypes(mItems); + } + + /** + * add an array of items to the end of the existing items + * + * @param items the items to add + */ + @SafeVarargs + public final ModelAdapter add(Model... items) { + return add(asList(items)); + } + + /** + * add a list of items to the end of the existing items + * + * @param list the items to add + */ + public ModelAdapter add(List list) { + List items = intercept(list); + return addInternal(items); + } + + public ModelAdapter addInternal(List items) { + if (mUseIdDistributor) { + IdDistributor.checkIds(items); + } + int countBefore = mItems.size(); + mItems.addAll(items); + mapPossibleTypes(items); + + if (mComparator == null) { + getFastAdapter().notifyAdapterItemRangeInserted(getFastAdapter().getPreItemCountByOrder(getOrder()) + countBefore, items.size()); + } else { + Collections.sort(mItems, mComparator); + getFastAdapter().notifyAdapterDataSetChanged(); + } + return this; + } + + /** + * add an array of items at the given position within the existing items + * + * @param position the global position + * @param items the items to add + */ + @SafeVarargs + public final ModelAdapter add(int position, Model... items) { + return add(position, asList(items)); + } + + /** + * add a list of items at the given position within the existing items + * + * @param position the global position + * @param list the items to add + */ + public ModelAdapter add(int position, List list) { + List items = intercept(list); + return addInternal(position, items); + } + + public ModelAdapter addInternal(int position, List items) { + if (mUseIdDistributor) { + IdDistributor.checkIds(items); + } + if (items != null && items.size() > 0) { + mItems.addAll(position - getFastAdapter().getPreItemCountByOrder(getOrder()), items); + mapPossibleTypes(items); + + getFastAdapter().notifyAdapterItemRangeInserted(position, items.size()); + } + return this; + } + + /** + * sets an item at the given position, overwriting the previous item + * + * @param position the global position + * @param element the item to set + */ + public ModelAdapter set(int position, Model element) { + Item item = intercept(element); + return setInternal(position, item); + } + + public ModelAdapter setInternal(int position, Item item) { + if (mUseIdDistributor) { + IdDistributor.checkId(item); + } + mItems.set(position - getFastAdapter().getPreItemCount(position), item); + mFastAdapter.registerTypeInstance(item); + + getFastAdapter().notifyAdapterItemChanged(position); + return this; + } + + /** + * moves an item within the list from a position to a position + * + * @param fromPosition the position global from which we want to move + * @param toPosition the global position to which to move + * @return this + */ + public ModelAdapter move(int fromPosition, int toPosition) { + int preItemCount = getFastAdapter().getPreItemCount(fromPosition); + Item item = mItems.get(fromPosition - preItemCount); + mItems.remove(fromPosition - preItemCount); + mItems.add(toPosition - preItemCount, item); + getFastAdapter().notifyAdapterItemMoved(fromPosition, toPosition); + return this; + } + + /** + * removes an item at the given position within the existing icons + * + * @param position the global position + */ + public ModelAdapter remove(int position) { + mItems.remove(position - getFastAdapter().getPreItemCount(position)); + getFastAdapter().notifyAdapterItemRemoved(position); + return this; + } + + /** + * removes a range of items starting with the given position within the existing icons + * + * @param position the global position + * @param itemCount the count of items which were removed + */ + public ModelAdapter removeRange(int position, int itemCount) { + //global position to relative + int length = mItems.size(); + int preItemCount = getFastAdapter().getPreItemCount(position); + //make sure we do not delete to many items + int saveItemCount = Math.min(itemCount, length - position + preItemCount); + + for (int i = 0; i < saveItemCount; i++) { + mItems.remove(position - preItemCount); + } + + getFastAdapter().notifyAdapterItemRangeRemoved(position, saveItemCount); + return this; + } + + /** + * removes all items of this adapter + */ + public ModelAdapter clear() { + int count = mItems.size(); + mItems.clear(); + getFastAdapter().notifyAdapterItemRangeRemoved(getFastAdapter().getPreItemCountByOrder(getOrder()), count); + return this; + } +} diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/items/AbstractItem.java b/library-core/src/main/java/com/mikepenz/fastadapter/items/AbstractItem.java index 5ed99d67e..7b0462746 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/items/AbstractItem.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/items/AbstractItem.java @@ -20,6 +20,7 @@ * Implements the general methods of the IItem interface to speed up development. */ public abstract class AbstractItem implements IItem, IClickable { + // the identifier for this item protected long mIdentifier = -1; diff --git a/library-extensions-expandable/src/main/java/com/mikepenz/fastadapter/expandable/ExpandableExtension.java b/library-extensions-expandable/src/main/java/com/mikepenz/fastadapter/expandable/ExpandableExtension.java index b9d06394b..1b78bf75b 100644 --- a/library-extensions-expandable/src/main/java/com/mikepenz/fastadapter/expandable/ExpandableExtension.java +++ b/library-extensions-expandable/src/main/java/com/mikepenz/fastadapter/expandable/ExpandableExtension.java @@ -394,7 +394,7 @@ public void expand(int position, boolean notifyItemChanged) { if (!expandable.isExpanded() && expandable.getSubItems() != null && expandable.getSubItems().size() > 0) { IAdapter adapter = mFastAdapter.getAdapter(position); if (adapter != null && adapter instanceof IItemAdapter) { - ((IItemAdapter) adapter).add(position + 1, expandable.getSubItems()); + ((IItemAdapter) adapter).add(position + 1, expandable.getSubItems()); } //remember that this item is now opened (not collapsed) diff --git a/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/UndoHelper.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/UndoHelper.java index 836dbfee6..9c953db1b 100644 --- a/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/UndoHelper.java +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/UndoHelper.java @@ -17,6 +17,8 @@ import java.util.SortedSet; import java.util.TreeSet; +import static java.util.Arrays.asList; + /** * Created by mikepenz on 04.01.16. */ @@ -85,7 +87,8 @@ public void onClick(View v) { }); } - public @Nullable Snackbar getSnackBar() { + public @Nullable + Snackbar getSnackBar() { return mSnackBar; } @@ -95,7 +98,8 @@ public void onClick(View v) { * @param positions the positions where the items were removed * @return the snackbar or null if {@link #withSnackBar(Snackbar, String)} was not previously called */ - public @Nullable Snackbar remove(Set positions) { + public @Nullable + Snackbar remove(Set positions) { if (mSnackBar == null) { return null; } @@ -214,8 +218,8 @@ private void undoChange() { for (int i = 0, size = mHistory.items.size(); i < size; i++) { FastAdapter.RelativeInfo relativeInfo = mHistory.items.get(i); if (relativeInfo.adapter instanceof IItemAdapter) { - IItemAdapter adapter = (IItemAdapter) relativeInfo.adapter; - adapter.add(relativeInfo.position, relativeInfo.item); + IItemAdapter adapter = (IItemAdapter) relativeInfo.adapter; + adapter.addInternal(relativeInfo.position, asList(relativeInfo.item)); if (relativeInfo.item.isSelected()) { mAdapter.select(relativeInfo.position); } diff --git a/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/scroll/EndlessScrollHelper.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/scroll/EndlessScrollHelper.java index c6246e6ee..a3da94f0c 100644 --- a/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/scroll/EndlessScrollHelper.java +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/scroll/EndlessScrollHelper.java @@ -7,8 +7,8 @@ import com.mikepenz.fastadapter.IItem; import com.mikepenz.fastadapter.IItemAdapter; -import com.mikepenz.fastadapter.adapters.ModelItemAdapter; import com.mikepenz.fastadapter.adapters.ItemAdapter; +import com.mikepenz.fastadapter.adapters.ModelItemAdapter; import com.mikepenz.fastadapter.utils.Function; import java.lang.ref.WeakReference; @@ -157,7 +157,7 @@ public EndlessScrollHelper withOnNewItemsListener(@NonNull OnNewItemsList * @return * @see #withNewItemsDeliveredTo(IItemAdapter, Function, OnNewItemsListener) withNewItemsDeliveredTo(IItemAdapter, Function, OnNewItemsListener) */ - public EndlessScrollHelper withNewItemsDeliveredTo(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory) { + public EndlessScrollHelper withNewItemsDeliveredTo(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory) { mOnNewItemsListener = new DeliverToIItemAdapter<>(itemAdapter, itemFactory); return this; } @@ -185,7 +185,7 @@ public EndlessScrollHelper withNewItemsDeliveredTo(@NonNull ModelItemAdap * @param * @return */ - public EndlessScrollHelper withNewItemsDeliveredTo(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory, @NonNull OnNewItemsListener extraOnNewItemsListener) { + public EndlessScrollHelper withNewItemsDeliveredTo(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory, @NonNull OnNewItemsListener extraOnNewItemsListener) { mOnNewItemsListener = new DeliverToIItemAdapter2<>(itemAdapter, itemFactory, extraOnNewItemsListener); return this; } @@ -311,11 +311,11 @@ public void run() { private static class DeliverToIItemAdapter implements OnNewItemsListener { @NonNull - private final IItemAdapter mItemAdapter; + private final IItemAdapter mItemAdapter; @NonNull private final Function mItemFactory; - DeliverToIItemAdapter(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory) { + DeliverToIItemAdapter(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory) { mItemAdapter = itemAdapter; mItemFactory = itemFactory; } @@ -327,7 +327,7 @@ public void onNewItems(@NonNull List newItems, int page) { for (int i = 0; i < size; i++) { iitems.add(mItemFactory.apply(newItems.get(i))); } - mItemAdapter.add(iitems); + mItemAdapter.addInternal(iitems); } } @@ -349,7 +349,7 @@ private static class DeliverToIItemAdapter2 extends D @NonNull private final OnNewItemsListener mExtraOnNewItemsListener; - DeliverToIItemAdapter2(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory, @NonNull OnNewItemsListener extraOnNewItemsListener) { + DeliverToIItemAdapter2(@NonNull IItemAdapter itemAdapter, @NonNull Function itemFactory, @NonNull OnNewItemsListener extraOnNewItemsListener) { super(itemAdapter, itemFactory); mExtraOnNewItemsListener = extraOnNewItemsListener; } diff --git a/library/src/main/java/com/mikepenz/fastadapter/commons/adapters/FastItemAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/commons/adapters/FastItemAdapter.java index e626ee48a..930b67fc4 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/commons/adapters/FastItemAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/commons/adapters/FastItemAdapter.java @@ -47,7 +47,7 @@ public FastItemAdapter withUseIdDistributor(boolean useIdDistributor) { /** * @return the filter used to filter items */ - public ItemFilter getItemFilter() { + public ItemFilter getItemFilter() { return getItemAdapter().getItemFilter(); } From fe743078fa10b41f2626b30aa99fee5c5fd5cf62 Mon Sep 17 00:00:00 2001 From: Fabian Terhorst Date: Sun, 16 Jul 2017 02:30:14 +0200 Subject: [PATCH 2/4] Add IdDistributor interface and add default interceptor implementation Add an IdDistributor interface to make id distribution to each item flexible and extendable. This change also stores the id distributor instance to the item adapter. The default implementation is stored static inside the interface so the atomic long is shared with all item adapters to not collicate with an second item adapter instance. --- .../mikepenz/fastadapter/IIdDistributor.java | 23 +++++++++++ .../mikepenz/fastadapter/IInterceptor.java | 8 ++++ .../fastadapter/adapters/ItemAdapter.java | 7 +--- .../fastadapter/adapters/ItemFilter.java | 7 ++-- .../fastadapter/adapters/ModelAdapter.java | 39 ++++++++++++++----- ...ributor.java => DefaultIdDistributor.java} | 18 +++++---- .../utils/DefaultIdDistributorImpl.java | 19 +++++++++ .../commons/utils/FastAdapterDiffUtil.java | 3 +- 8 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 library-core/src/main/java/com/mikepenz/fastadapter/IIdDistributor.java rename library-core/src/main/java/com/mikepenz/fastadapter/utils/{IdDistributor.java => DefaultIdDistributor.java} (63%) create mode 100644 library-core/src/main/java/com/mikepenz/fastadapter/utils/DefaultIdDistributorImpl.java diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/IIdDistributor.java b/library-core/src/main/java/com/mikepenz/fastadapter/IIdDistributor.java new file mode 100644 index 000000000..2730d7781 --- /dev/null +++ b/library-core/src/main/java/com/mikepenz/fastadapter/IIdDistributor.java @@ -0,0 +1,23 @@ +package com.mikepenz.fastadapter; + +import android.support.annotation.NonNull; + +import com.mikepenz.fastadapter.utils.DefaultIdDistributorImpl; + +import java.util.List; + +/** + * Created by fabianterhorst on 16.07.17. + */ +public interface IIdDistributor { + + IIdDistributor DEFAULT = new DefaultIdDistributorImpl<>(); + + List checkIds(@NonNull List items); + + Identifiable[] checkIds(@NonNull Identifiable... items); + + Identifiable checkId(@NonNull Identifiable item); + + long nextId(Identifiable item); +} diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java b/library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java index 4e563eef6..b36f99660 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/IInterceptor.java @@ -4,5 +4,13 @@ * Created by mikepenz on 30.12.15. */ public interface IInterceptor { + + IInterceptor DEFAULT = new IInterceptor() { + @Override + public IItem intercept(IItem item) { + return item; + } + }; + Item intercept(Element element); } diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java index 531957314..ee5fe4b8c 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java @@ -10,12 +10,7 @@ public class ItemAdapter extends ModelAdapter { public ItemAdapter() { - super(new IInterceptor() { - @Override - public Item intercept(Item item) { - return item; - } - }); + super((IInterceptor) IInterceptor.DEFAULT); } /** diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java index 91ec6a5e8..e4248d4d9 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ItemFilter.java @@ -6,7 +6,6 @@ import com.mikepenz.fastadapter.IItem; import com.mikepenz.fastadapter.IItemAdapter; import com.mikepenz.fastadapter.listeners.ItemFilterListener; -import com.mikepenz.fastadapter.utils.IdDistributor; import java.util.ArrayList; import java.util.HashSet; @@ -207,7 +206,7 @@ public final ModelAdapter add(Item... items) { public ModelAdapter add(List items) { if (mOriginalItems != null && items.size() > 0) { if (mItemAdapter.isUseIdDistributor()) { - IdDistributor.checkIds(items); + mItemAdapter.getIdDistributor().checkIds(items); } mOriginalItems.addAll(items); publishResults(mConstraint, performFiltering(mConstraint)); @@ -237,7 +236,7 @@ public final ModelAdapter add(int position, Item... items) { public ModelAdapter add(int position, List items) { if (mOriginalItems != null && items.size() > 0) { if (mItemAdapter.isUseIdDistributor()) { - IdDistributor.checkIds(items); + mItemAdapter.getIdDistributor().checkIds(items); } mOriginalItems.addAll(getAdapterPosition(mItemAdapter.getAdapterItems().get(position)) - mItemAdapter.getFastAdapter().getPreItemCount(position), items); publishResults(mConstraint, performFiltering(mConstraint)); @@ -256,7 +255,7 @@ public ModelAdapter add(int position, List items) { public ModelAdapter set(int position, Item item) { if (mOriginalItems != null) { if (mItemAdapter.isUseIdDistributor()) { - IdDistributor.checkId(item); + mItemAdapter.getIdDistributor().checkId(item); } mOriginalItems.set(getAdapterPosition(mItemAdapter.getAdapterItems().get(position)) - mItemAdapter.getFastAdapter().getPreItemCount(position), item); publishResults(mConstraint, performFiltering(mConstraint)); diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java index 22bb5b845..a96d3e4ea 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/adapters/ModelAdapter.java @@ -5,10 +5,11 @@ import com.mikepenz.fastadapter.AbstractAdapter; import com.mikepenz.fastadapter.IAdapterExtension; +import com.mikepenz.fastadapter.IIdDistributor; import com.mikepenz.fastadapter.IInterceptor; import com.mikepenz.fastadapter.IItem; import com.mikepenz.fastadapter.IItemAdapter; -import com.mikepenz.fastadapter.utils.IdDistributor; +import com.mikepenz.fastadapter.utils.DefaultIdDistributorImpl; import java.util.ArrayList; import java.util.Collections; @@ -61,13 +62,33 @@ private List intercept(List models) { return items; } - //defines if the IdDistributor is used to set ID's to all added items + private IIdDistributor mIdDistributor; + + /** + * defines the idDistributor that is used to provide an ID to all added items + * + * @param idDistributor the idDistributor to use + * @return this + */ + public ModelAdapter withIdDistributor(IIdDistributor idDistributor) { + this.mIdDistributor = idDistributor; + return this; + } + + public IIdDistributor getIdDistributor() { + if (mIdDistributor == null) { + return (IIdDistributor) IIdDistributor.DEFAULT; + } + return mIdDistributor; + } + + //defines if the DefaultIdDistributor is used to set ID's to all added items private boolean mUseIdDistributor = true; /** - * defines if the IdDistributor is used to provide an ID to all added items which do not yet define an id + * defines if the DefaultIdDistributor is used to provide an ID to all added items which do not yet define an id * - * @param useIdDistributor false if the IdDistributor shouldn't be used + * @param useIdDistributor false if the DefaultIdDistributor shouldn't be used * @return this */ public ModelAdapter withUseIdDistributor(boolean useIdDistributor) { @@ -235,7 +256,7 @@ protected ModelAdapter set(List list, boolean resetFilter) { public ModelAdapter setInternal(List items, boolean resetFilter) { if (mUseIdDistributor) { - IdDistributor.checkIds(items); + getIdDistributor().checkIds(items); } //reset the filter @@ -312,7 +333,7 @@ public ModelAdapter setNewList(List list, boolean retainFilt List items = intercept(list); if (mUseIdDistributor) { - IdDistributor.checkIds(items); + getIdDistributor().checkIds(items); } //reset the filter @@ -368,7 +389,7 @@ public ModelAdapter add(List list) { public ModelAdapter addInternal(List items) { if (mUseIdDistributor) { - IdDistributor.checkIds(items); + getIdDistributor().checkIds(items); } int countBefore = mItems.size(); mItems.addAll(items); @@ -407,7 +428,7 @@ public ModelAdapter add(int position, List list) { public ModelAdapter addInternal(int position, List items) { if (mUseIdDistributor) { - IdDistributor.checkIds(items); + getIdDistributor().checkIds(items); } if (items != null && items.size() > 0) { mItems.addAll(position - getFastAdapter().getPreItemCountByOrder(getOrder()), items); @@ -431,7 +452,7 @@ public ModelAdapter set(int position, Model element) { public ModelAdapter setInternal(int position, Item item) { if (mUseIdDistributor) { - IdDistributor.checkId(item); + getIdDistributor().checkId(item); } mItems.set(position - getFastAdapter().getPreItemCount(position), item); mFastAdapter.registerTypeInstance(item); diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/utils/IdDistributor.java b/library-core/src/main/java/com/mikepenz/fastadapter/utils/DefaultIdDistributor.java similarity index 63% rename from library-core/src/main/java/com/mikepenz/fastadapter/utils/IdDistributor.java rename to library-core/src/main/java/com/mikepenz/fastadapter/utils/DefaultIdDistributor.java index 4fb008e7f..28c397da2 100644 --- a/library-core/src/main/java/com/mikepenz/fastadapter/utils/IdDistributor.java +++ b/library-core/src/main/java/com/mikepenz/fastadapter/utils/DefaultIdDistributor.java @@ -2,16 +2,15 @@ import android.support.annotation.NonNull; +import com.mikepenz.fastadapter.IIdDistributor; import com.mikepenz.fastadapter.IIdentifyable; import java.util.List; -import java.util.concurrent.atomic.AtomicLong; /** * Created by mikepenz on 19.09.15. */ -public class IdDistributor { - private static final AtomicLong idDistributor = new AtomicLong(-2L); +public abstract class DefaultIdDistributor implements IIdDistributor { /** * set an unique identifier for all items which do not have one set already @@ -19,7 +18,8 @@ public class IdDistributor { * @param items * @return */ - public static List checkIds(@NonNull List items) { + @Override + public List checkIds(@NonNull List items) { for (int i = 0, size = items.size(); i < size; i++) { checkId(items.get(i)); } @@ -32,8 +32,9 @@ public static List checkIds(@NonNull List items) * @param items * @return */ - public static T[] checkIds(@NonNull T... items) { - for (T item : items) { + @Override + public Identifiable[] checkIds(@NonNull Identifiable... items) { + for (Identifiable item : items) { checkId(item); } return items; @@ -45,9 +46,10 @@ public static T[] checkIds(@NonNull T... items) { * @param item * @return */ - public static T checkId(@NonNull T item) { + @Override + public Identifiable checkId(@NonNull Identifiable item) { if (item.getIdentifier() == -1) { - item.withIdentifier(idDistributor.decrementAndGet()); + item.withIdentifier(nextId(item)); } return item; } diff --git a/library-core/src/main/java/com/mikepenz/fastadapter/utils/DefaultIdDistributorImpl.java b/library-core/src/main/java/com/mikepenz/fastadapter/utils/DefaultIdDistributorImpl.java new file mode 100644 index 000000000..92ca341db --- /dev/null +++ b/library-core/src/main/java/com/mikepenz/fastadapter/utils/DefaultIdDistributorImpl.java @@ -0,0 +1,19 @@ +package com.mikepenz.fastadapter.utils; + +import com.mikepenz.fastadapter.IIdDistributor; +import com.mikepenz.fastadapter.IIdentifyable; + +import java.util.concurrent.atomic.AtomicLong; + +/** + * Created by mikepenz on 19.09.15. + */ +public class DefaultIdDistributorImpl extends DefaultIdDistributor { + + private final AtomicLong idDistributor = new AtomicLong(-2L); + + @Override + public long nextId(Identifiable identifiable) { + return idDistributor.decrementAndGet(); + } +} diff --git a/library/src/main/java/com/mikepenz/fastadapter/commons/utils/FastAdapterDiffUtil.java b/library/src/main/java/com/mikepenz/fastadapter/commons/utils/FastAdapterDiffUtil.java index 02ffe32af..8ed3d939a 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/commons/utils/FastAdapterDiffUtil.java +++ b/library/src/main/java/com/mikepenz/fastadapter/commons/utils/FastAdapterDiffUtil.java @@ -6,7 +6,6 @@ import com.mikepenz.fastadapter.IItem; import com.mikepenz.fastadapter.adapters.ItemAdapter; -import com.mikepenz.fastadapter.utils.IdDistributor; import java.util.Collections; import java.util.List; @@ -18,7 +17,7 @@ public class FastAdapterDiffUtil { public static , Item extends IItem> A set(final A adapter, final List items, final DiffCallback callback, final boolean detectMoves) { if (adapter.isUseIdDistributor()) { - IdDistributor.checkIds(items); + adapter.getIdDistributor().checkIds(items); } //if we have a comparator then sort From c94dff0d95785f0035ffd832e81521cdebfbed15 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 16 Jul 2017 09:04:35 +0200 Subject: [PATCH 3/4] * new v3 snapshot release * add script to simplify release --- app/build.gradle | 4 ++-- library-core/build.gradle | 2 +- library-core/gradle.properties | 4 ++-- library-extensions-expandable/build.gradle | 4 ++-- library-extensions-expandable/gradle.properties | 4 ++-- library-extensions/build.gradle | 4 ++-- library-extensions/gradle.properties | 4 ++-- library/build.gradle | 4 ++-- library/gradle.properties | 4 ++-- release.sh | 14 ++++++++++++++ 10 files changed, 31 insertions(+), 17 deletions(-) create mode 100755 release.sh diff --git a/app/build.gradle b/app/build.gradle index a2a493ad9..55d668530 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 25 - versionCode 3005 - versionName '3.0.0.5-SNAPSHOT' + versionCode 3006 + versionName '3.0.0.6-SNAPSHOT' } buildTypes { debug { diff --git a/library-core/build.gradle b/library-core/build.gradle index 6b369da84..cca2c8cf8 100644 --- a/library-core/build.gradle +++ b/library-core/build.gradle @@ -10,7 +10,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 25 - versionCode 3005 + versionCode 3006 versionName '3.0.0.5' } buildTypes { diff --git a/library-core/gradle.properties b/library-core/gradle.properties index 765ec90a1..47d98e597 100755 --- a/library-core/gradle.properties +++ b/library-core/gradle.properties @@ -1,5 +1,5 @@ POM_NAME=FastAdapter Library POM_ARTIFACT_ID=fastadapter POM_PACKAGING=aar -VERSION_NAME=3.0.0.5-SNAPSHOT -VERSION_CODE=3005 +VERSION_NAME=3.0.0.6-SNAPSHOT +VERSION_CODE=3006 diff --git a/library-extensions-expandable/build.gradle b/library-extensions-expandable/build.gradle index 91cc011e7..47c98b94b 100644 --- a/library-extensions-expandable/build.gradle +++ b/library-extensions-expandable/build.gradle @@ -9,8 +9,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 25 - versionCode 3005 - versionName '3.0.0.5-SNAPSHOT' + versionCode 3006 + versionName '3.0.0.6-SNAPSHOT' } buildTypes { release { diff --git a/library-extensions-expandable/gradle.properties b/library-extensions-expandable/gradle.properties index ac62a6fb7..5092b1067 100755 --- a/library-extensions-expandable/gradle.properties +++ b/library-extensions-expandable/gradle.properties @@ -1,5 +1,5 @@ POM_NAME=FastAdapter Library-Extensions-Expandable POM_ARTIFACT_ID=fastadapter-extensions-expandable POM_PACKAGING=aar -VERSION_NAME=3.0.0.5-SNAPSHOT -VERSION_CODE=3005 \ No newline at end of file +VERSION_NAME=3.0.0.6-SNAPSHOT +VERSION_CODE=3006 \ No newline at end of file diff --git a/library-extensions/build.gradle b/library-extensions/build.gradle index afc820bc1..225f26da9 100644 --- a/library-extensions/build.gradle +++ b/library-extensions/build.gradle @@ -9,8 +9,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 25 - versionCode 3005 - versionName '3.0.0.5-SNAPSHOT' + versionCode 3006 + versionName '3.0.0.6-SNAPSHOT' } buildTypes { release { diff --git a/library-extensions/gradle.properties b/library-extensions/gradle.properties index 643145a67..15bbb8805 100755 --- a/library-extensions/gradle.properties +++ b/library-extensions/gradle.properties @@ -1,5 +1,5 @@ POM_NAME=FastAdapter Library-Extensions POM_ARTIFACT_ID=fastadapter-extensions POM_PACKAGING=aar -VERSION_NAME=3.0.0.5-SNAPSHOT -VERSION_CODE=3005 \ No newline at end of file +VERSION_NAME=3.0.0.6-SNAPSHOT +VERSION_CODE=3006 \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index 5c4ba0e71..c06586b21 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -9,8 +9,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 25 - versionCode 3005 - versionName '3.0.0.5-SNAPSHOT' + versionCode 3006 + versionName '3.0.0.6-SNAPSHOT' } buildTypes { release { diff --git a/library/gradle.properties b/library/gradle.properties index ee14364a5..82d634a77 100755 --- a/library/gradle.properties +++ b/library/gradle.properties @@ -1,5 +1,5 @@ POM_NAME=FastAdapter Library POM_ARTIFACT_ID=fastadapter-commons POM_PACKAGING=aar -VERSION_NAME=3.0.0.5-SNAPSHOT -VERSION_CODE=3005 \ No newline at end of file +VERSION_NAME=3.0.0.6-SNAPSHOT +VERSION_CODE=3006 \ No newline at end of file diff --git a/release.sh b/release.sh new file mode 100755 index 000000000..3225e319f --- /dev/null +++ b/release.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [ "$1" = "release" ]; +then + ./gradlew clean build uploadArchives generatePomFileForReleasePublication bintrayUpload Plibrarycoreonly + ./gradlew build uploadArchives generatePomFileForReleasePublication bintrayUpload -x test -Plibrarycommonsonly + ./gradlew build uploadArchives generatePomFileForReleasePublication bintrayUpload -x test -Plibraryextensiononly + ./gradlew build uploadArchives generatePomFileForReleasePublication bintrayUpload -x test -libraryextensionexpandablemonly +else + ./gradlew clean build uploadArchives -Plibrarycoreonly + ./gradlew build uploadArchives -x test -Plibrarycommonsonly + ./gradlew build uploadArchives -x test -Plibraryextensiononly + ./gradlew build uploadArchives -x test -libraryextensionexpandablemonly +fi \ No newline at end of file From 47244d0865c376050112e6c3919ce323d6822b8a Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Sun, 16 Jul 2017 09:07:14 +0200 Subject: [PATCH 4/4] * oops. typo in script --- release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release.sh b/release.sh index 3225e319f..1d197a4eb 100755 --- a/release.sh +++ b/release.sh @@ -5,10 +5,10 @@ then ./gradlew clean build uploadArchives generatePomFileForReleasePublication bintrayUpload Plibrarycoreonly ./gradlew build uploadArchives generatePomFileForReleasePublication bintrayUpload -x test -Plibrarycommonsonly ./gradlew build uploadArchives generatePomFileForReleasePublication bintrayUpload -x test -Plibraryextensiononly - ./gradlew build uploadArchives generatePomFileForReleasePublication bintrayUpload -x test -libraryextensionexpandablemonly + ./gradlew build uploadArchives generatePomFileForReleasePublication bintrayUpload -x test -Plibraryextensionexpandablemonly else ./gradlew clean build uploadArchives -Plibrarycoreonly ./gradlew build uploadArchives -x test -Plibrarycommonsonly ./gradlew build uploadArchives -x test -Plibraryextensiononly - ./gradlew build uploadArchives -x test -libraryextensionexpandablemonly + ./gradlew build uploadArchives -x test -Plibraryextensionexpandablemonly fi \ No newline at end of file