2016-04-30 79 views
0

我編寫了類來表示樹文件層次結構。主要任務 - 標記文件和文件夾(使用複選框)的功能。面臨這樣的問題:消失的父目錄的對勾與行動的順序如下:Android:如何解決意外取消選中樹中父節點的複選框

0)進入根目錄,檢查文件(留一個目錄選中)

1)轉到未經檢查的目錄,並檢查任何文件(或更多)

2)返回到一個更高的水平,並取消了目錄,在其中進行操作(1)

返回到一個更高的水平,你會看到父目錄的複選標記未被選中(儘管在根目錄中至少有一個選中的文件)。

多年來,我一直在尋找一個問題。也許有人會注意到這個錯誤。先謝謝你。

截圖:

Bug

Normal state

類:

public class FileTree { 
    /* The name for pointer to the parent node */ 
    public static final String PARENT_DIR = ".."; 

    private String mName; 
    private boolean mIsLeaf; 
    private boolean mIsChecked = false; 
    private long mSize; 
    /* Number of checked children */ 
    private int childrenCheckNum = 0; 
    private FileTree mParent; 
    private Map<String, FileTree> mChildren = new LinkedHashMap<String, FileTree>(); 

    public FileTree(String name, long size, int type) 
    { 
     this(name, size, type, null); 
    } 

    public FileTree(String name, long size, int type, FileTree parent) 
    { 
     mName = name; 
     mIsLeaf = type == FileNode.Type.FILE; 
     mParent = parent; 
     mSize = size; 
    } 

    public void addChild(FileTree node) 
    { 
     if (!mChildren.containsKey(node.getName())) { 
      mChildren.put(node.getName(), node); 
      mSize += node.size(); 
      if (mParent != null) { 
       mParent.onChildAdd(node.size()); 
      } 
     } 
    } 

    /* 
    * Sending new child size up the tree. 
    */ 

    private void onChildAdd(long size) 
    { 
     mSize += size; 
     if (mParent != null) { 
      mParent.onChildAdd(size); 
     } 
    } 

    public boolean findChild(String name) 
    { 
     if (mChildren.containsKey(name)) { 
      return true; 
     } 

     return false; 
    } 

    ... 

    public boolean isChecked() 
    { 
     return mIsChecked; 
    } 

    public void setCheck(boolean check) 
    { 
     mIsChecked = check; 

     /* Sending check change event up the parent */ 
     if (mParent != null && mParent.isChecked() != check) { 
      mParent.onChildCheckChange(check); 
     } 

     /* Sending check change event down the tree */ 
     if (getChildrenCount() != 0) { 
      childrenCheckNum = check ? getChildrenCount() : 0; 

      for (FileTree node : mChildren.values()) { 
       if (node.isChecked() != check) { 
        node.setCheck(check); 
       } 
      } 
     } 
    } 

    /* 
    * Sending check change events up the tree. 
    */ 

    private void onChildCheckChange(boolean check) 
    { 
     if (check) { 
      ++childrenCheckNum; 
      mIsChecked = true; 
     } else { 
      if (childrenCheckNum > 0) { 
       --childrenCheckNum; 
      } 

      /* Uncheck parent only if don't left selected children nodes */ 
      if (childrenCheckNum == 0) { 
       mIsChecked = false; 
      } 
     } 

     /* Sending check change event up the parent */ 
     if (mParent != null && mParent.isChecked() != check) { 
      mParent.onChildCheckChange(check); 
     } 
    } 
    ... 
} 

回答

0

我已經簡化onChildCheckChanged,現在它工作正常

private synchronized void onChildCheckChange() 
    { 
     if (getChildrenCount() == 0) { 
      return; 
     } 

     long childrenCheckNum = 0; 
     for (FileTree child : children.values()) { 
      if (child.isChecked) { 
       ++childrenCheckNum; 
      } 
     } 

     /* Uncheck parent only if don't left selected children nodes */ 
     isChecked = childrenCheckNum > 0; 

     /* Sending check change event up the parent */ 
     if (parent != null && parent.isChecked() != isChecked) { 
      parent.onChildCheckChange(); 
     } 
    } 
相關問題