Search in sources :

Example 1 with IExpandable

use of com.mikepenz.fastadapter.IExpandable in project FastAdapter by mikepenz.

the class SubItemUtil method notifyItemsChanged.

/**
     * notifies items (incl. sub items if they are currently extended)
     *
     * @param adapter the adapter
     * @param identifiers set of identifiers that should be notified
     * @param restoreExpandedState true, if expanded headers should stay expanded
     */
public static <Item extends IItem & IExpandable> void notifyItemsChanged(final FastAdapter adapter, Set<Long> identifiers, boolean restoreExpandedState) {
    int i;
    IItem item;
    for (i = 0; i < adapter.getItemCount(); i++) {
        item = adapter.getItem(i);
        if (item instanceof IExpandable) {
            notifyItemsChanged(adapter, (Item) item, identifiers, true, restoreExpandedState);
        } else if (identifiers.contains(item.getIdentifier())) {
            adapter.notifyAdapterItemChanged(i);
        }
    }
}
Also used : IExpandable(com.mikepenz.fastadapter.IExpandable) IItem(com.mikepenz.fastadapter.IItem)

Example 2 with IExpandable

use of com.mikepenz.fastadapter.IExpandable in project FastAdapter by mikepenz.

the class SubItemUtil method deleteSelected.

/**
     * deletes all selected items from the adapter respecting if the are sub items or not
     * subitems are removed from their parents sublists, main items are directly removed
     *
     * @param deleteEmptyHeaders if true, empty headers will be removed from the adapter
     * @return List of items that have been removed from the adapter
     */
public static List<IItem> deleteSelected(final FastAdapter fastAdapter, boolean notifyParent, boolean deleteEmptyHeaders) {
    List<IItem> deleted = new ArrayList<>();
    // we use a LinkedList, because this has performance advantages when modifying the listIterator during iteration!
    // Modifying list is O(1)
    LinkedList<IItem> selectedItems = new LinkedList<>(getSelectedItems(fastAdapter));
    //        Log.d("DELETE", "selectedItems: " + selectedItems.size());
    // we delete item per item from the adapter directly or from the parent
    // if keepEmptyHeaders is false, we add empty headers to the selected items set via the iterator, so that they are processed in the loop as well
    IItem item, parent;
    int pos, parentPos;
    boolean expanded;
    ListIterator<IItem> it = selectedItems.listIterator();
    while (it.hasNext()) {
        item = it.next();
        pos = fastAdapter.getPosition(item);
        // search for parent - if we find one, we remove the item from the parent's subitems directly
        parent = getParent(item);
        if (parent != null) {
            parentPos = fastAdapter.getPosition(parent);
            boolean success = ((IExpandable) parent).getSubItems().remove(item);
            // check if parent is expanded and notify the adapter about the removed item, if necessary (only if parent is visible)
            if (parentPos != -1 && ((IExpandable) parent).isExpanded()) {
                fastAdapter.notifyAdapterSubItemsChanged(parentPos, ((IExpandable) parent).getSubItems().size() + 1);
            }
            // if desired, notify the parent about its changed items (only if parent is visible!)
            if (parentPos != -1 && notifyParent) {
                expanded = ((IExpandable) parent).isExpanded();
                fastAdapter.notifyAdapterItemChanged(parentPos);
                // expand the item again if it was expanded before calling notifyAdapterItemChanged
                if (expanded) {
                    fastAdapter.expand(parentPos);
                }
            }
            deleted.add(item);
            if (deleteEmptyHeaders && ((IExpandable) parent).getSubItems().size() == 0) {
                it.add(parent);
                it.previous();
            }
        } else if (pos != -1) {
            // if we did not find a parent, we remove the item from the adapter
            IAdapter adapter = fastAdapter.getAdapter(pos);
            boolean success = false;
            if (adapter instanceof IItemAdapter) {
                success = ((IItemAdapter) adapter).remove(pos) != null;
            }
            boolean isHeader = item instanceof IExpandable && ((IExpandable) item).getSubItems() != null;
            //                Log.d("DELETE", "success=" + success + " | deletedId=" + item.getIdentifier() + "(" + (isHeader ? "EMPTY HEADER" : "ITEM WITHOUT HEADER") + ")");
            deleted.add(item);
        }
    }
    return deleted;
}
Also used : IExpandable(com.mikepenz.fastadapter.IExpandable) ArrayList(java.util.ArrayList) IItemAdapter(com.mikepenz.fastadapter.IItemAdapter) IItem(com.mikepenz.fastadapter.IItem) IAdapter(com.mikepenz.fastadapter.IAdapter) LinkedList(java.util.LinkedList)

Example 3 with IExpandable

use of com.mikepenz.fastadapter.IExpandable in project FastAdapter by mikepenz.

the class SubItemUtil method getAllItems.

/**
     * internal function!
     *
     * Why countHeaders and subItems => because the subItemsOnly is an internal flag for the recursive call to optimise it!
     */
private static List<IItem> getAllItems(List<IItem> items, boolean countHeaders, boolean subItemsOnly, IPredicate predicate) {
    List<IItem> res = new ArrayList<>();
    if (items == null || items.size() == 0) {
        return res;
    }
    int temp;
    int itemCount = items.size();
    IItem item;
    List<IItem> subItems;
    for (int i = 0; i < itemCount; i++) {
        item = items.get(i);
        if (item instanceof IExpandable && ((IExpandable) item).getSubItems() != null) {
            subItems = ((IExpandable) item).getSubItems();
            if (predicate == null) {
                if (countHeaders) {
                    res.add(item);
                }
                if (subItems != null && subItems.size() > 0) {
                    res.addAll(subItems);
                }
                res.addAll(getAllItems(subItems, countHeaders, true, predicate));
            } else {
                if (countHeaders && predicate.apply(item)) {
                    res.add(item);
                }
                temp = subItems != null ? subItems.size() : 0;
                for (int j = 0; j < temp; j++) {
                    if (predicate.apply(subItems.get(j))) {
                        res.add(subItems.get(j));
                    }
                }
            }
        } else // sub items will be counted in above if statement!
        if (!subItemsOnly && getParent(item) == null) {
            if (predicate == null) {
                res.add(item);
            } else if (predicate.apply(item)) {
                res.add(item);
            }
        }
    }
    return res;
}
Also used : IExpandable(com.mikepenz.fastadapter.IExpandable) ArrayList(java.util.ArrayList) IItem(com.mikepenz.fastadapter.IItem)

Example 4 with IExpandable

use of com.mikepenz.fastadapter.IExpandable in project FastAdapter by mikepenz.

the class SubItemUtil method delete.

/**
     * deletes all items in identifiersToDelete collection from the adapter respecting if there are sub items or not
     * subitems are removed from their parents sublists, main items are directly removed
     *
     * @param fastAdapter the adapter to remove the items from
     * @param identifiersToDelete ids of items to remove
     * @param notifyParent if true, headers of removed items will be notified about the change of their child items
     * @param deleteEmptyHeaders if true, empty headers will be removed from the adapter
     * @return List of items that have been removed from the adapter
     */
public static List<IItem> delete(final FastAdapter fastAdapter, Collection<Long> identifiersToDelete, boolean notifyParent, boolean deleteEmptyHeaders) {
    List<IItem> deleted = new ArrayList<>();
    if (identifiersToDelete == null || identifiersToDelete.size() == 0) {
        return deleted;
    }
    // we use a LinkedList, because this has performance advantages when modifying the listIterator during iteration!
    // Modifying list is O(1)
    LinkedList<Long> identifiers = new LinkedList<>(identifiersToDelete);
    // we delete item per item from the adapter directly or from the parent
    // if keepEmptyHeaders is false, we add empty headers to the selected items set via the iterator, so that they are processed in the loop as well
    IItem item, parent;
    int pos, parentPos;
    boolean expanded;
    Long identifier;
    ListIterator<Long> it = identifiers.listIterator();
    while (it.hasNext()) {
        identifier = it.next();
        pos = fastAdapter.getPosition(identifier);
        item = fastAdapter.getItem(pos);
        // search for parent - if we find one, we remove the item from the parent's subitems directly
        parent = getParent(item);
        if (parent != null) {
            parentPos = fastAdapter.getPosition(parent);
            boolean success = ((IExpandable) parent).getSubItems().remove(item);
            // check if parent is expanded and notify the adapter about the removed item, if necessary (only if parent is visible)
            if (parentPos != -1 && ((IExpandable) parent).isExpanded()) {
                fastAdapter.notifyAdapterSubItemsChanged(parentPos, ((IExpandable) parent).getSubItems().size() + 1);
            }
            // if desired, notify the parent about it's changed items (only if parent is visible!)
            if (parentPos != -1 && notifyParent) {
                expanded = ((IExpandable) parent).isExpanded();
                fastAdapter.notifyAdapterItemChanged(parentPos);
                // expand the item again if it was expanded before calling notifyAdapterItemChanged
                if (expanded) {
                    fastAdapter.expand(parentPos);
                }
            }
            deleted.add(item);
            if (deleteEmptyHeaders && ((IExpandable) parent).getSubItems().size() == 0) {
                it.add(parent.getIdentifier());
                it.previous();
            }
        } else if (pos != -1) {
            // if we did not find a parent, we remove the item from the adapter
            IAdapter adapter = fastAdapter.getAdapter(pos);
            boolean success = false;
            if (adapter instanceof IItemAdapter) {
                success = ((IItemAdapter) adapter).remove(pos) != null;
                if (success) {
                    fastAdapter.notifyAdapterItemRemoved(pos);
                }
            }
            boolean isHeader = item instanceof IExpandable && ((IExpandable) item).getSubItems() != null;
            //                Log.d("DELETE", "success=" + success + " | deletedId=" + item.getIdentifier() + "(" + (isHeader ? "EMPTY HEADER" : "ITEM WITHOUT HEADER") + ")");
            deleted.add(item);
        }
    }
    return deleted;
}
Also used : IExpandable(com.mikepenz.fastadapter.IExpandable) ArrayList(java.util.ArrayList) IItemAdapter(com.mikepenz.fastadapter.IItemAdapter) IItem(com.mikepenz.fastadapter.IItem) IAdapter(com.mikepenz.fastadapter.IAdapter) LinkedList(java.util.LinkedList)

Example 5 with IExpandable

use of com.mikepenz.fastadapter.IExpandable in project FastAdapter by mikepenz.

the class SubItemUtil method notifyItemsChanged.

/**
     * notifies items (incl. sub items if they are currently extended)
     *
     * @param adapter the adapter
     * @param header the expandable header that should be checked (incl. sub items)
     * @param identifiers set of identifiers that should be notified
     * @param checkSubItems true, if sub items of headers items should be checked recursively
     * @param restoreExpandedState true, if expanded headers should stay expanded
     */
public static <Item extends IItem & IExpandable> void notifyItemsChanged(final FastAdapter adapter, Item header, Set<Long> identifiers, boolean checkSubItems, boolean restoreExpandedState) {
    int subItems = header.getSubItems().size();
    int position = adapter.getPosition(header);
    boolean expanded = header.isExpanded();
    // 1) check header itself
    if (identifiers.contains(header.getIdentifier())) {
        adapter.notifyAdapterItemChanged(position);
    }
    // 2) check sub items, recursively
    IItem item;
    if (header.isExpanded()) {
        for (int i = 0; i < subItems; i++) {
            item = (IItem) header.getSubItems().get(i);
            if (identifiers.contains(item.getIdentifier())) {
                //                    Log.d("NOTIFY", "Position=" + position + ", i=" + i);
                adapter.notifyAdapterItemChanged(position + i + 1);
            }
            if (checkSubItems && item instanceof IExpandable) {
                notifyItemsChanged(adapter, (Item) item, identifiers, true, restoreExpandedState);
            }
        }
    }
    if (restoreExpandedState && expanded) {
        adapter.expand(position);
    }
}
Also used : IExpandable(com.mikepenz.fastadapter.IExpandable) IItem(com.mikepenz.fastadapter.IItem)

Aggregations

IExpandable (com.mikepenz.fastadapter.IExpandable)11 IItem (com.mikepenz.fastadapter.IItem)10 ArrayList (java.util.ArrayList)6 IAdapter (com.mikepenz.fastadapter.IAdapter)3 List (java.util.List)3 RecyclerView (android.support.v7.widget.RecyclerView)2 View (android.view.View)2 FastAdapter (com.mikepenz.fastadapter.FastAdapter)2 IItemAdapter (com.mikepenz.fastadapter.IItemAdapter)2 LinkedList (java.util.LinkedList)2 Handler (android.os.Handler)1 ActionMode (android.support.v7.view.ActionMode)1 DefaultItemAnimator (android.support.v7.widget.DefaultItemAnimator)1 LinearLayoutManager (android.support.v7.widget.LinearLayoutManager)1 Toolbar (android.support.v7.widget.Toolbar)1 LinearLayout (android.widget.LinearLayout)1 StickyHeaderAdapter (com.mikepenz.fastadapter.app.adapters.StickyHeaderAdapter)1 ActionModeHelper (com.mikepenz.fastadapter_extensions.ActionModeHelper)1 IconicsLayoutInflater (com.mikepenz.iconics.context.IconicsLayoutInflater)1 AbstractDrawerItem (com.mikepenz.materialdrawer.model.AbstractDrawerItem)1