0
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());
        }
    }
}

我有一个项目列表,每个项目都是子项目或父项目。根父项的 parentId 等于 0,子项的 parentId 等于其父项的 id。

子项也可以在其下方有子项。

我需要做这样的事情。如果我单击其中一个项目,我需要它的所有子项在它们展开时折叠或在它们折叠时展开。

除了一件事,我的代码有效。假设我折叠一个孩子的子项,然后我折叠一个父母,其孩子是我已经折叠的孩子之一。然后那些孩子扩大,但我不希望他们扩大,因为我刚刚试图折叠他们更高的父母。

谁能帮我解决这个问题

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;
    }

}
4

2 回答 2

1

Instead of toggling the state at every level independently of the other levels, the code needs to decide whether it's collapsing or expanding the nodes, and then pass that decision down the recursive call tree.

于 2013-08-14T16:49:47.343 回答
1

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.
于 2013-08-14T16:50:36.823 回答