reusing TreeNode structure
I've created TreeNode structure and used it with AndroidTreeView. When I'm trying to reuse this structure with new AndroidTreeView I receive error
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:3936)
at android.view.ViewGroup.addView(ViewGroup.java:3786)
at android.view.ViewGroup.addView(ViewGroup.java:3727)
at android.view.ViewGroup.addView(ViewGroup.java:3700)
at com.unnamed.b.atv.view.AndroidTreeView.addNode(AndroidTreeView.java:228)
at com.unnamed.b.atv.view.AndroidTreeView.expandNode(AndroidTreeView.java:210)
at com.unnamed.b.atv.view.AndroidTreeView.getView(AndroidTreeView.java:106)
at com.unnamed.b.atv.view.AndroidTreeView.getView(AndroidTreeView.java:111)
The problem is in ViewHolder. Before reusing ViewHolder we should set mView to null, but it is impossible now.
For now I have to use such hack
void cleanTreeNodes(List<TreeNode> treeNodes) {
for (TreeNode treeNode : treeNodes) {
TreeNode.BaseNodeViewHolder viewHolder = treeNode.getViewHolder();
try {
TreeNode.BaseNodeViewHolder viewHolder2 = viewHolder.getClass().getDeclaredConstructor(Context.class).newInstance(this);
treeNode.setViewHolder(viewHolder2);
viewHolder2.setContainerStyle(viewHolder.getContainerStyle());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
cleanTreeNodes(treeNode.getChildren());
}
}
You can not reuse TreeNode structure, is it possible for you to re-create that structure?
yes it is possible, but why can't we just add a method for cleaning views?
Can you explain this bug a little more? I have the same problem and I do not think I understand the issue. I am trying to fix the issue with something like
((ViewGroup) treeView.getParent()).removeView(treeView);
@dogauzun, my idea was to force viewHolder generate new view for each node. Your way is simpler. If you want to reuse views, which have been generated already, you can remove views of first level nodes from parent layout, something like this:
((ViewGroup)mRoot.getChildren().get(0).getViewHolder().getView().getParent()).removeAllViews();
I solved this with the following code:
//Used this treeView previously
if (treeView != null)
containerView.removeAllViews();
treeView = AndroidTreeView(getActivity(), root);
//...etc...
containerView.addView(treeView.getView());
works just fine
None of the above solutions are working for me. I am using a fragment and I initialize the treeview when i fetch some data from the network. It works fine for the first time but getView method throws an IllegalState exception on the second time. I am recreating Treenodes and viewholders from scratch each time.
I solved this with the following code: if(tView == null) { Log.d("aaa","tView is null"); tView = new AndroidTreeView(getActivity(), root); tView.setDefaultAnimation(true); tView.setDefaultContainerStyle(R.style.TreeNodeStyleCustom); tView.setDefaultViewHolder(IconTreeItemHolder.class); tView.setDefaultNodeClickListener(nodeClickListener); tView.setDefaultNodeLongClickListener(nodeLongClickListener); root=TreeNode.root();
// ((ViewGroup) containerView.getParent()).removeView(tView.getView());
containerView.addView(tView.getView());
}else{
Log.d("aaa", "tView is not null");
containerView.removeAllViews();
tView = new AndroidTreeView(getActivity(), root);
tView.setDefaultAnimation(true);
tView.setDefaultContainerStyle(R.style.TreeNodeStyleCustom);
tView.setDefaultViewHolder(IconTreeItemHolder.class);
tView.setDefaultNodeClickListener(nodeClickListener);
tView.setDefaultNodeLongClickListener(nodeLongClickListener);
root=TreeNode.root();
containerView.addView(tView.getView());
}
@dogauzun I have the same issue with you. Have you fixed it now?
I solved my problem with moving my tree initialization method from onCreateView to onStart method in my fragment. I was trying to avoid initializing my tree everytime my fragment becomes visible but in my use case the tree structure is actually not that big so I stopped trying to do that.
None of the above solutions are working for me. Has anybody found the right solution ?
ok
On Wed, May 4, 2016 at 2:19 PM, ministorm [email protected] wrote:
@dogauzun https://github.com/dogauzun I have the same issue with you. Have you fixed it now?
— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/bmelnychuk/AndroidTreeView/issues/25#issuecomment-216815089
private void clearViewHolders(List<TreeNode> treeNodes) {
for (TreeNode node : treeNodes) {
if (node.getViewHolder() instanceof TreeStepViewHolder) {
node.setViewHolder(null);
TreeStepViewHolder treeStepViewHolder = new TreeStepViewHolder(getContext());
treeStepViewHolder.setContainerStyle(R.style.TreeNodeStyleCustom);
node.setViewHolder(treeStepViewHolder);
} else if (node.getViewHolder() instanceof TreeFailureViewHolder) {
node.setViewHolder(null);
TreeFailureViewHolder treeFailureViewHolder = new TreeFailureViewHolder(getContext());
treeFailureViewHolder.setContainerStyle(R.style.TreeNodeStyleCustom);
node.setViewHolder(treeFailureViewHolder);
}
clearViewHolders(node.getChildren());
}
}
This works for me.
Thank you all of above, help me solving the problem of refresh tree node with data changed. here is my code , if anyone need:
if (layout != null) {//layout is the view you inflated in method createView,keep a reference to class field
layout.removeAllViews();
TreeNode newroot = TreeNode.root();
fillTreeData(newroot, contextEvents);
AndroidTreeView newTree = new AndroidTreeView(getActivity(), newroot);
newTree.setDefaultAnimation(true);
newTree.setDefaultViewHolder(MyTreeViewHolder.class);
newTree.setDefaultContainerStyle(R.style.TreeNodeStyle);
layout.addView(newTree.getView());
}
these code can be called outside of method createView in fragment.
I have same question, I solved my problem with fixing IconTreeItemHolder.java