Search in sources :

Example 16 with IHeader

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++;
            }
        }
    }
}
Also used : IHeader(eu.davidea.flexibleadapter.items.IHeader) IExpandable(eu.davidea.flexibleadapter.items.IExpandable) SuppressLint(android.annotation.SuppressLint)

Example 17 with IHeader

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);
            }
        }
    }
}
Also used : IHeader(eu.davidea.flexibleadapter.items.IHeader) ISectionable(eu.davidea.flexibleadapter.items.ISectionable)

Example 18 with IHeader

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));
}
Also used : IHeader(eu.davidea.flexibleadapter.items.IHeader) ISectionable(eu.davidea.flexibleadapter.items.ISectionable) SuppressLint(android.annotation.SuppressLint)

Example 19 with IHeader

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);
            }
        }
    }
}
Also used : IHeader(eu.davidea.flexibleadapter.items.IHeader) ISectionable(eu.davidea.flexibleadapter.items.ISectionable) SuppressLint(android.annotation.SuppressLint)

Example 20 with IHeader

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;
}
Also used : IHeader(eu.davidea.flexibleadapter.items.IHeader)

Aggregations

IHeader (eu.davidea.flexibleadapter.items.IHeader)21 SuppressLint (android.annotation.SuppressLint)8 ISectionable (eu.davidea.flexibleadapter.items.ISectionable)8 Test (org.junit.Test)4 AbstractFlexibleItem (eu.davidea.flexibleadapter.items.AbstractFlexibleItem)3 IExpandable (eu.davidea.flexibleadapter.items.IExpandable)3 TodoListHeaderViewModel (de.djuelg.neuronizer.presentation.ui.flexibleadapter.TodoListHeaderViewModel)2 ArrayList (java.util.ArrayList)2 TodoListHeader (de.djuelg.neuronizer.domain.model.todolist.TodoListHeader)1 IFlexible (eu.davidea.flexibleadapter.items.IFlexible)1 AbstractItem (eu.davidea.samples.flexibleadapter.items.AbstractItem)1 ExpandableHeaderItem (eu.davidea.samples.flexibleadapter.items.ExpandableHeaderItem)1 HeaderItem (eu.davidea.samples.flexibleadapter.items.HeaderItem)1 InstagramHeaderItem (eu.davidea.samples.flexibleadapter.items.InstagramHeaderItem)1 StaggeredHeaderItem (eu.davidea.samples.flexibleadapter.items.StaggeredHeaderItem)1 List (java.util.List)1