简体   繁体   中英

How can I implement this recursive algorithm to toggle some values on and off depending on their parent's value in a hierarchy

protected boolean toggleChildVisibility(long itemId) {
    for (int i = 0; i < items.size(); i++) {
        if (items.get(i).getParentItemId() == itemId) {
            Item childItem = items.get(i);

            childItem.setCollapsed(!childItem.isCollapsed());

            toggleChildVisibility(childItem.getItemId());
        }
    }
}

I have a list of items, each item either a child or parent item. the root parent items have parentId equal to 0, the children have parentId equal to their parent's id.

Child items can also have child items below them as well.

I need to do something like this. if I click one of them items I need all of its children to collapse if they're expanded or expand if they're collapsed.

The code I have works except for one thing. Say I collapse a child's children items, then I collapse a parent whose children is one of the children I already collapsed. then those children expand, but I don't want them to expand because I have just tried to collapse a higher parent of theirs.

Can anyone help me fix it so that children do not expand when parent is collapsed if they were already collapased

public class Item {
    long questionId;
    int depth;

    boolean  collapsed,childrenCollapsed;

    public boolean isChildrenCollapsed() {
        return childrenCollapsed;
    }

    public void setChildrenCollapsed(boolean childrenCollapsed) {
        this.childrenCollapsed = childrenCollapsed;
    }

    public boolean isCollapsed() {
        return collapsed;
    }

    public void setCollapsed(boolean collapsed) {
        this.collapsed = collapsed;
    }
    public long getDepth() {
        return depth;
    }

    public void setDepth(int depth) {
        this.depth = depth;
    }

}

代码不是独立于其他级别切换每个级别的状态,而是需要决定它是折叠还是扩展节点,然后将该决策传递给递归调用树。

Probably you want to do something like this:

public void toggleNodeCollapseState(int itemId) {
     for (int i = 0; i < items.size(); i++) {
        Item childItem = items.get(i);
        if (childItem.getParentItemId() == itemId) {
            childItem.setCollapsed(!childItem.isCollapsed);
            if (childItem.isCollapsed) {
                hideItemAndDescendants(childItem);
            } else {
                showDescendants(childItem);
            }
        }
     }
}

public void hideItemAndDescendants(Item item) {
    item.hide();
    for (int i = 0; i < items.size(); i++) {
        Item childItem = items.get(i);
        if (childItem.getId() == item.getId()) {
              hideItemAndDescendants(childItem);
        }
    }
}

public void showDescendants(Item item) {
    item.hide();
    for (int i = 0; i < items.size(); i++) {
        Item childItem = items.get(i);
        if (childItem.getId() == item.getId()) {
            childItem.show();
            if (!childItem.isCollapsed()) {
                showDescendants(childItem);
            }
        }
    }
}

The key is that there are two issues with nodes

  1. Are they collapsed?
  2. Are they visible? Or hidden?

You can ignore this distinction but that will result in a collapse always collapsing all the descendants. That means you can't have a node with uncollapsed children showing the grandchildren, collapse the node, uncollapse the node and see those grandchildren in the same collapse state as they were. (I find it particularly irritating to click the wrong node and get everything I carefully expanded below that node collapsed so I have to redo it.)

Clicking a node will then need to toggle the collapsed state.

  • A node that is collapsed gets all its descendants hidden but it is still visible.
  • A node that's not collapsed gets all its direct children un-hidden.
    • If those direct children are not collapsed apply the rule that an uncollapsed node's children are visible. So their direct children (the grandchildren of the original node) are un-hidden and we go on down un-hiding nodes that are not collapsed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM