简体   繁体   English

如何实现此递归算法以根据其父级在层次结构中的值来打开和关闭某些值

[英]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. 根父项的parentId等于0,子节点的parentId等于其父节点的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. 因此,他们的直接孩子(原始节点的孙子)是未隐藏的,我们继续关闭未隐藏的未隐藏节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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