Search in sources :

Example 1 with IExpandable

use of eu.davidea.flexibleadapter.items.IExpandable in project FlexibleAdapter by davideas.

the class FlexibleAdapter method removeRange.

/**
	 * Removes a list of consecutive items and notify the change.
	 * <p>If the item, resulting from the provided position:</p>
	 * - is <u>not expandable</u> with <u>no</u> parent, it is removed as usual.<br/>
	 * - is <u>not expandable</u> with a parent, it is removed only if the parent is expanded.<br/>
	 * - is <u>expandable</u> implementing {@link IExpandable}, it is removed as usual, but
	 * it will be collapsed if expanded.<br/>
	 * - has a {@link IHeader} item, the header will be automatically linked to the first item
	 * after the range or can remain orphan.
	 * <p>Optionally you can pass any payload to notify the <u>parent</u> or the <u>header</u>
	 * about the change and optimize the view binding.</p>
	 *
	 * @param positionStart the start position of the first item
	 * @param itemCount     how many items should be removed
	 * @param payload       any non-null user object to notify the parent (the payload will be
	 *                      therefore passed to the bind method of the parent ViewHolder),
	 *                      pass null to <u>not</u> notify the parent
	 * @see #clear()
	 * @see #clearAllBut(Integer...)
	 * @see #removeItem(int, Object)
	 * @see #removeItems(List, Object)
	 * @see #removeRange(int, int)
	 * @see #removeAllSelectedItems(Object)
	 * @see #setPermanentDelete(boolean)
	 * @see #setRestoreSelectionOnUndo(boolean)
	 * @see #getDeletedItems()
	 * @see #getDeletedChildren(IExpandable)
	 * @see #restoreDeletedItems()
	 * @see #startUndoTimer(long, OnDeleteCompleteListener)
	 * @see #emptyBin()
	 * @since 5.0.0-b1
	 */
//FIXME: Fix payload message if customized
public void removeRange(@IntRange(from = 0) int positionStart, @IntRange(from = 0) int itemCount, @Nullable Object payload) {
    int initialCount = getItemCount();
    if (DEBUG)
        Log.d(TAG, "removeRange positionStart=" + positionStart + " itemCount=" + itemCount);
    if (positionStart < 0 || (positionStart + itemCount) > initialCount) {
        Log.e(TAG, "Cannot removeRange with positionStart out of OutOfBounds!");
        return;
    }
    // Update content of the header linked to first item of the range
    T item = getItem(positionStart);
    IHeader header = getHeaderOf(item);
    int headerPosition = getGlobalPositionOf(header);
    if (header != null && headerPosition >= 0) {
        // The header does not represents a group anymore, add it to the Orphan list
        addToOrphanListIfNeeded(header, positionStart, itemCount);
        notifyItemChanged(headerPosition, payload);
    }
    int parentPosition = -1;
    IExpandable parent = null;
    for (int position = positionStart; position < positionStart + itemCount; position++) {
        item = getItem(positionStart);
        if (!permanentDelete) {
            //When removing a range of children, parent is always the same :-)
            if (parent == null)
                parent = getExpandableOf(item);
            //Differentiate: (Expandable & NonExpandable with No parent) from (NonExpandable with a parent)
            if (parent == null) {
                createRestoreItemInfo(positionStart, item, Payload.UNDO);
            } else {
                parentPosition = createRestoreSubItemInfo(parent, item, Payload.UNDO);
            }
        }
        // Change to hidden status for section headers
        if (isHeader(item)) {
            header = (IHeader) item;
            header.setHidden(true);
            // If item is a Header, remove linkage from ALL Sectionable items if exist
            if (unlinkOnRemoveHeader) {
                List<ISectionable> sectionableList = getSectionItems(header);
                for (ISectionable sectionable : sectionableList) {
                    sectionable.setHeader(null);
                    if (payload != null)
                        notifyItemChanged(getGlobalPositionOf(sectionable), Payload.UNLINK);
                }
            }
        }
        // Remove item from internal list
        mItems.remove(positionStart);
        removeSelection(position);
    }
    // Notify range removal
    notifyItemRangeRemoved(positionStart, itemCount);
    // Notify the Parent about the change if requested
    if (parentPosition >= 0 && payload != null) {
        notifyItemChanged(parentPosition, payload);
    }
    // Remove orphan headers
    if (removeOrphanHeaders) {
        for (IHeader orphanHeader : mOrphanHeaders) {
            headerPosition = getGlobalPositionOf(orphanHeader);
            if (headerPosition >= 0) {
                if (DEBUG)
                    Log.v(TAG, "Removing orphan header " + orphanHeader);
                if (!permanentDelete)
                    createRestoreItemInfo(headerPosition, (T) orphanHeader, Payload.UNDO);
                mItems.remove(headerPosition);
                notifyItemRemoved(headerPosition);
            }
        }
        mOrphanHeaders.clear();
    }
    // Update empty view
    if (mUpdateListener != null && !multiRange && initialCount > 0 && getItemCount() == 0)
        mUpdateListener.onUpdateEmptyView(getMainItemCount());
}
Also used : IHeader(eu.davidea.flexibleadapter.items.IHeader) IExpandable(eu.davidea.flexibleadapter.items.IExpandable) ISectionable(eu.davidea.flexibleadapter.items.ISectionable) SuppressLint(android.annotation.SuppressLint)

Example 2 with IExpandable

use of eu.davidea.flexibleadapter.items.IExpandable in project FlexibleAdapter by davideas.

the class FlexibleAdapter method addFilteredSubItems.

/**
	 * Adds to the final list also the filtered subItems.
	 */
private int addFilteredSubItems(List<T> values, T item) {
    if (isExpandable(item)) {
        IExpandable expandable = (IExpandable) item;
        if (hasSubItems(expandable)) {
            // Add subItems if not hidden by filterObject()
            List<T> filteredSubItems = new ArrayList<>();
            List<T> subItems = expandable.getSubItems();
            for (T subItem : subItems) {
                if (!subItem.isHidden())
                    filteredSubItems.add(subItem);
            }
            values.addAll(filteredSubItems);
            return filteredSubItems.size();
        }
    }
    return 0;
}
Also used : IExpandable(eu.davidea.flexibleadapter.items.IExpandable) ArrayList(java.util.ArrayList)

Example 3 with IExpandable

use of eu.davidea.flexibleadapter.items.IExpandable in project FlexibleAdapter by davideas.

the class FlexibleAdapter method expandAll.

/**
	 * Expands all IExpandable items with at least the specified level.
	 * <p>Parent will be notified.</p>
	 *
	 * @param level the minimum level to expand the sub expandable items
	 * @return the number of parent successfully expanded
	 * @see #expandAll()
	 * @see #setMinCollapsibleLevel(int)
	 * @since 5.0.0-b6
	 */
public int expandAll(int level) {
    int expanded = 0;
    // More efficient if we expand from First expandable position
    int startPosition = Math.max(0, mScrollableHeaders.size() - 1);
    for (int i = startPosition; i < (getItemCount() - mScrollableFooters.size()); i++) {
        T item = getItem(i);
        if (isExpandable(item)) {
            IExpandable expandable = (IExpandable) item;
            if (expandable.getExpansionLevel() <= level && expand(i, true, false, true) > 0) {
                i += expandable.getSubItems().size();
                expanded++;
            }
        }
    }
    return expanded;
}
Also used : IExpandable(eu.davidea.flexibleadapter.items.IExpandable) SuppressLint(android.annotation.SuppressLint)

Example 4 with IExpandable

use of eu.davidea.flexibleadapter.items.IExpandable in project FlexibleAdapter by davideas.

the class FlexibleAdapter method collapse.

/**
	 * Collapses an {@code IExpandable} item that is already expanded, if no subItem is selected.
	 * <p>Multilevel behaviour: all {@code IExpandable} subItem, that are expanded, are recursively
	 * collapsed.</p>
	 *
	 * @param position     the position of the item to collapse
	 * @param notifyParent notify the parent with {@link Payload#COLLAPSED}
	 * @return the number of subItems collapsed
	 * @see #collapseAll()
	 * @since 5.0.0-b1
	 */
public int collapse(@IntRange(from = 0) int position, boolean notifyParent) {
    T item = getItem(position);
    if (!isExpandable(item))
        return 0;
    IExpandable expandable = (IExpandable) item;
    // Take the current subList (will improve the performance when collapseAll)
    List<T> subItems = getExpandableList(expandable);
    int subItemsCount = subItems.size(), recursiveCount = 0;
    if (DEBUG && mHashItems == null) {
        Log.v(TAG, "Request to Collapse on position=" + position + " expanded=" + expandable.isExpanded() + " hasSubItemsSelected=" + hasSubItemsSelected(position, subItems));
    }
    if (expandable.isExpanded() && subItemsCount > 0 && (!hasSubItemsSelected(position, subItems) || getPendingRemovedItem(item) != null)) {
        // Recursive collapse of all sub expandable
        recursiveCount = recursiveCollapse(position + 1, subItems, expandable.getExpansionLevel());
        mItems.removeAll(subItems);
        subItemsCount = subItems.size();
        // Save expanded state
        expandable.setExpanded(false);
        // Collapse!
        if (notifyParent)
            notifyItemChanged(position, Payload.COLLAPSED);
        notifyItemRangeRemoved(position + 1, subItemsCount);
        // Hide also the headers of the subItems
        if (headersShown && !isHeader(item)) {
            for (T subItem : subItems) {
                hideHeaderOf(subItem);
            }
        }
        // Expandable as a Scrollable Header/Footer
        if (!collapseSHF(mScrollableHeaders, expandable))
            collapseSHF(mScrollableFooters, expandable);
        if (DEBUG)
            Log.v(TAG, "Collapsed " + subItemsCount + " subItems on position " + position);
    }
    return subItemsCount + recursiveCount;
}
Also used : IExpandable(eu.davidea.flexibleadapter.items.IExpandable) SuppressLint(android.annotation.SuppressLint)

Example 5 with IExpandable

use of eu.davidea.flexibleadapter.items.IExpandable in project FlexibleAdapter by davideas.

the class FlexibleAdapter method resetFilterFlags.

/**
	 * Clears flags after searchText is cleared out for Expandable items and sub items.
	 */
private void resetFilterFlags(List<T> items) {
    // 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
            if (mExpandedFilterFlags != null)
                expandable.setExpanded(mExpandedFilterFlags.contains(expandable));
            if (hasSubItems(expandable)) {
                List<T> subItems = expandable.getSubItems();
                for (T subItem : subItems) {
                    // Reset subItem hidden flag
                    subItem.setHidden(false);
                    // Show subItems for expanded items
                    if (expandable.isExpanded()) {
                        i++;
                        if (i < items.size())
                            items.add(i, subItem);
                        else
                            items.add(subItem);
                    }
                }
            }
        }
    }
    mExpandedFilterFlags = null;
}
Also used : IExpandable(eu.davidea.flexibleadapter.items.IExpandable) SuppressLint(android.annotation.SuppressLint)

Aggregations

IExpandable (eu.davidea.flexibleadapter.items.IExpandable)11 SuppressLint (android.annotation.SuppressLint)5 AbstractFlexibleItem (eu.davidea.flexibleadapter.items.AbstractFlexibleItem)1 IHeader (eu.davidea.flexibleadapter.items.IHeader)1 ISectionable (eu.davidea.flexibleadapter.items.ISectionable)1 ExpandableItem (eu.davidea.samples.flexibleadapter.items.ExpandableItem)1 SimpleItem (eu.davidea.samples.flexibleadapter.items.SimpleItem)1 SubItem (eu.davidea.samples.flexibleadapter.items.SubItem)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1