use of eu.davidea.flexibleadapter.items.IHeader in project FlexibleAdapter by davideas.
the class FlexibleAdapter method resetFilterFlags.
/**
* Clears flags after filter is cleared out for Expandable items and sub items.
* Also restore headers visibility.
*/
private void resetFilterFlags(List<T> items) {
if (items == null) {
return;
}
IHeader sameHeader = null;
// Reset flags for all items!
for (int i = 0; i < items.size(); i++) {
T item = items.get(i);
item.setHidden(false);
if (isExpandable(item)) {
IExpandable expandable = (IExpandable) item;
// Reset expanded flag
expandable.setExpanded(mExpandedFilterFlags != null && mExpandedFilterFlags.contains(expandable));
if (hasSubItems(expandable)) {
List<T> subItems = expandable.getSubItems();
// Reset subItem hidden flag2
for (T subItem : subItems) {
subItem.setHidden(false);
if (subItem instanceof IExpandable) {
IExpandable subExpandable = (IExpandable) subItem;
subExpandable.setExpanded(false);
resetFilterFlags(subExpandable.getSubItems());
}
}
// Show subItems for expanded items
if (expandable.isExpanded() && mOriginalList == null) {
if (i < items.size()) {
items.addAll(i + 1, subItems);
} else {
items.addAll(subItems);
}
i += subItems.size();
}
}
}
// Restore headers visibility
if (headersShown && mOriginalList == null) {
IHeader header = getHeaderOf(item);
if (header != null && !header.equals(sameHeader) && !isExpandable((T) header)) {
header.setHidden(false);
sameHeader = header;
items.add(i, (T) header);
i++;
}
}
}
}
use of eu.davidea.flexibleadapter.items.IHeader in project FlexibleAdapter by davideas.
the class FlexibleAdapter method unlinkHeaderFrom.
/**
* Internal method to unlink the header from the specified item.
* <p>Used by the Adapter during the Remove/Restore/Move operations.</p>
*
* @param item the item that holds the header
* @param payload any non-null user object to notify the header and the item (the payload
* will be therefore passed to the bind method of the items ViewHolder),
* pass null to <u>not</u> notify the header and item
* @since 5.0.0-b6
*/
private void unlinkHeaderFrom(T item, @Nullable Object payload) {
if (hasHeader(item)) {
ISectionable sectionable = (ISectionable) item;
IHeader header = sectionable.getHeader();
log.v("Unlink header %s from %s", header, sectionable);
sectionable.setHeader(null);
// Notify items
if (payload != null) {
if (!header.isHidden()) {
notifyItemChanged(getGlobalPositionOf(header), payload);
}
if (!item.isHidden()) {
notifyItemChanged(getGlobalPositionOf(item), payload);
}
}
}
}
use of eu.davidea.flexibleadapter.items.IHeader in project FlexibleAdapter by davideas.
the class FlexibleAdapter method calculatePositionFor.
/**
* New method to extract the new position where the item should lay.
* <p><b>Note: </b>The {@code Comparator} object should be customized to support <u>all</u>
* types of items this Adapter is managing or a {@code ClassCastException} will be raised.</p>
* If the {@code Comparator} is {@code null} the returned position is 0 (first position).
*
* @param item the item to evaluate the insertion
* @param comparator the Comparator object with the logic to sort the list
* @return the position resulted from sorting with the provided Comparator
* @since 5.0.0-b7
*/
public int calculatePositionFor(@NonNull Object item, @Nullable Comparator<IFlexible> comparator) {
// There's nothing to compare
if (comparator == null) {
return 0;
}
// Header is visible
if (item instanceof ISectionable) {
ISectionable sectionable = (ISectionable) item;
IHeader header = sectionable.getHeader();
if (header != null && !header.isHidden()) {
List<ISectionable> sortedList = getSectionItems(header);
sortedList.add(sectionable);
Collections.sort(sortedList, comparator);
int itemPosition = getGlobalPositionOf(sectionable);
int headerPosition = getGlobalPositionOf(header);
// #143 - calculatePositionFor() missing a +1 when addItem (fixed by condition: itemPosition != -1)
// fix represents the situation when item is before the target position (used in moveItem)
int fix = itemPosition != -1 && itemPosition < headerPosition ? 0 : 1;
int result = headerPosition + sortedList.indexOf(item) + fix;
log.v("Calculated finalPosition=%s sectionPosition=%s relativePosition=%s fix=%s", result, headerPosition, sortedList.indexOf(item), fix);
return result;
}
}
// All other cases
List sortedList = new ArrayList<>(mItems);
if (!sortedList.contains(item)) {
sortedList.add(item);
}
Collections.sort(sortedList, comparator);
log.v("Calculated position %s for item=%s", Math.max(0, sortedList.indexOf(item)), item);
return Math.max(0, sortedList.indexOf(item));
}
use of eu.davidea.flexibleadapter.items.IHeader in project FlexibleAdapter by davideas.
the class FlexibleAdapter method swapItems.
/**
* Swaps the elements of list at indices fromPosition and toPosition and notify the change.
* <p>Selection of swiped elements is automatically updated.</p>
*
* @param fromPosition previous position of the item.
* @param toPosition new position of the item.
* @since 5.0.0-b7
*/
public void swapItems(List<T> list, int fromPosition, int toPosition) {
if (fromPosition < 0 || fromPosition >= getItemCount() || toPosition < 0 || toPosition >= getItemCount()) {
return;
}
log.v("swapItems from=%s [selected? %s] to=%s [selected? %s]", fromPosition, isSelected(fromPosition), toPosition, isSelected(toPosition));
// Collapse expandable before swapping (otherwise items are mixed badly)
if (fromPosition < toPosition && isExpandable(getItem(fromPosition)) && isExpanded(toPosition)) {
collapse(toPosition);
}
// Perform item swap (for all LayoutManagers)
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
log.v("swapItems from=%s to=%s", i, (i + 1));
Collections.swap(list, i, i + 1);
swapSelection(i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
log.v("swapItems from=%s to=%s", i, (i - 1));
Collections.swap(list, i, i - 1);
swapSelection(i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
// Header swap linkage
if (headersShown) {
// Situation AFTER items have been swapped, items are inverted!
T fromItem = getItem(toPosition);
T toItem = getItem(fromPosition);
int oldPosition, newPosition;
if (toItem instanceof IHeader && fromItem instanceof IHeader) {
if (fromPosition < toPosition) {
// Dragging down fromHeader
// Auto-linkage all section-items with new header
IHeader header = (IHeader) fromItem;
List<ISectionable> items = getSectionItems(header);
for (ISectionable sectionable : items) {
linkHeaderTo((T) sectionable, header, Payload.LINK);
}
} else {
// Dragging up fromHeader
// Auto-linkage all section-items with new header
IHeader header = (IHeader) toItem;
List<ISectionable> items = getSectionItems(header);
for (ISectionable sectionable : items) {
linkHeaderTo((T) sectionable, header, Payload.LINK);
}
}
} else if (toItem instanceof IHeader) {
// A Header is being swapped up
// Else a Header is being swapped down
oldPosition = fromPosition < toPosition ? toPosition + 1 : toPosition;
newPosition = fromPosition < toPosition ? toPosition : fromPosition + 1;
// Swap header linkage
linkHeaderTo(getItem(oldPosition), getSectionHeader(oldPosition), Payload.LINK);
linkHeaderTo(getItem(newPosition), (IHeader) toItem, Payload.LINK);
} else if (fromItem instanceof IHeader) {
// A Header is being dragged down
// Else a Header is being dragged up
oldPosition = fromPosition < toPosition ? fromPosition : fromPosition + 1;
newPosition = fromPosition < toPosition ? toPosition + 1 : fromPosition;
// Swap header linkage
linkHeaderTo(getItem(oldPosition), getSectionHeader(oldPosition), Payload.LINK);
linkHeaderTo(getItem(newPosition), (IHeader) fromItem, Payload.LINK);
} else {
// A Header receives the toItem
// Else a Header receives the fromItem
oldPosition = fromPosition < toPosition ? toPosition : fromPosition;
newPosition = fromPosition < toPosition ? fromPosition : toPosition;
// Swap header linkage
T oldItem = getItem(oldPosition);
IHeader header = getHeaderOf(oldItem);
if (header != null) {
IHeader oldHeader = getSectionHeader(oldPosition);
if (oldHeader != null && !oldHeader.equals(header)) {
linkHeaderTo(oldItem, oldHeader, Payload.LINK);
}
linkHeaderTo(getItem(newPosition), header, Payload.LINK);
}
}
}
}
use of eu.davidea.flexibleadapter.items.IHeader in project FlexibleAdapter by davideas.
the class FlexibleAdapter method showHeaderOf.
/**
* Internal method to show/add a header in the internal list.
*
* @param position the position where the header will be displayed
* @param item the item that holds the header
* @param init for silent initialization: skip notifyItemInserted
* @since 5.0.0-b1
*/
private boolean showHeaderOf(int position, T item, boolean init) {
// Take the header
IHeader header = getHeaderOf(item);
// Check header existence
if (header == null || getPendingRemovedItem(item) != null) {
return false;
}
if (header.isHidden()) {
log.v("Showing header position=%s header=%s", position, header);
header.setHidden(false);
// Insert header, but skip notifyItemInserted when init=true!
// We are adding headers to the provided list at startup (no need to notify)
performInsert(position, Collections.singletonList((T) header), !init);
return true;
}
return false;
}
Aggregations