bmelnychuk / AndroidTreeView

AndroidTreeView. TreeView implementation for android
Apache License 2.0
3k stars 621 forks source link

Strange treeView.getView() returns null #30

Closed Odaym closed 9 years ago

Odaym commented 9 years ago

This code runs through my parent Task objects and for each one of its children, it gets the children and adds them to that parent, then to the root, then again for all the remaining parents. At the end, it makes a new AndroidTreeView and set its properties and then should add that TreeView to the containerView I have defined (RelativeLayout cast into ViewGroup), just as your code says. processTasks(allTasks) is called only once.

Seems strange that there would be an exception and I looked through all the issues, no one faced this..any help would be appreciated, thanks!

    public void processTasks(List<Task> allTasks) {
        final TreeNode root = TreeNode.root();

        for (Task task : allTasks) {
            TreeNode parentNode = new TreeNode(task).setViewHolder(new TaskTreeItemHolder(getActivity()));
            processTaskChildren(task, root, parentNode);
        }

        AndroidTreeView taskTreeView = new AndroidTreeView(getActivity(), root);
        taskTreeView.setDefaultAnimation(true);
        taskTreeView.setDefaultContainerStyle(R.style.TreeNodeStyleDivided, true);

        //Returns null here (Attempt to invoke virtual method 'android.content.Context android.view.View.getContext()' on a null object reference)
        // It's referring to the taskTreeView.getView() because naturally the exception would have mentioned the exception on addView instead
        taskListContainer.addView(taskTreeView.getView());
    }

    public void processTaskChildren(Task parentTask, TreeNode rootNode, TreeNode parentNode) {
        List<Task> childrenTasks = taskDAO.queryForEq("ParentTaskId", parentTask.getTask_id());

        for (Task child : childrenTasks) {
            TreeNode taskChildNode = new TreeNode(child).setViewHolder(new TaskTreeItemHolder(getActivity()));
            parentNode.addChild(taskChildNode);
            processTaskChildren(child, rootNode, parentNode);
        }

        rootNode.addChild(parentNode);
    }
bmelnychuk commented 9 years ago

Maybe you can try to simplify you tree structure and see if it is actually working. processTasks looks fine for me but processTaskChildren is not clear for me. Do you really need two TreeNode params? Should not you use taskChildNode for recursion call in cycle? I would assume something like:

public void processTasks(List<Task> allTasks) {
    final TreeNode root = TreeNode.root();
    for (Task task : allTasks) {            
        processTaskChildren(task, root);
    }

    AndroidTreeView taskTreeView = new AndroidTreeView(getActivity(), root);
    taskTreeView.setDefaultAnimation(true);
    taskTreeView.setDefaultContainerStyle(R.style.TreeNodeStyleDivided, true);

    taskListContainer.addView(taskTreeView.getView());
}

public void processTaskChildren(Task parentTask, TreeNode parentNode) {
    TreeNode taskNode = new TreeNode(parentTask).setViewHolder(new TaskTreeItemHolder(getActivity()));
    parentNode.addChild(taskNode);

    List<Task> childrenTasks = taskDAO.queryForEq("ParentTaskId", parentTask.getTask_id());
    for (Task child : childrenTasks) {            
           processTaskChildren(child, taskNode);
    }
}

Did not try this, hope you'll get the idea

Odaym commented 9 years ago

Thanks that you took the time to answer, I did try to simplify and got the same exception. I got it as simple as

TreeNode taskNode = new TreeNode(parentTask).setViewHolder(new TaskTreeItemHolder(getActivity()));
    parentNode.addChild(taskNode);

just to see if it would work, still get the exception. It seems like an obvious or trivial issue. What do you think could cause this? an Incorrectly implemented ViewHolder? here's the TaskTreeItemHolder I've written:

public class TaskTreeItemHolder extends TreeNode.BaseNodeViewHolder<Task> {
    private View taskStatusBar;
    private TextView taskNameTV;
    private TextView projectNameTV;
    private TextView taskStartDateTV;
    private TextView taskEndDateTV;
    private ImageView expandTaskIMG;

    private Context mContext;

    public TaskTreeItemHolder(Context context) {
        super(context);

        mContext = context;
    }

    @Override
    public View createNodeView(TreeNode treeNode, Task taskTreeItem) {
        final LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.task_list_item, null, false);

        taskNameTV = (TextView) view.findViewById(R.id.taskNameTV);
        projectNameTV = (TextView) view.findViewById(R.id.projectNameTV);
        taskStartDateTV = (TextView) view.findViewById(R.id.taskStartDateTV);
        taskEndDateTV = (TextView) view.findViewById(R.id.taskEndDateTV);
        taskStatusBar = view.findViewById(R.id.statusBarView);
        expandTaskIMG = (ImageView) view.findViewById(R.id.expandTaskIMG);

        taskNameTV.setText(taskTreeItem.getTaskName());
        projectNameTV.setText(taskTreeItem.getProjectName());
        taskStartDateTV.setText(taskTreeItem.getStartDate());
        taskEndDateTV.setText(taskTreeItem.getEndDate());

        switch (taskTreeItem.getTaskStatusId()) {
            case 0:
                taskStatusBar.setBackgroundColor(mContext.getResources().getColor(R.color.task_new));
                break;
            case 1:
                taskStatusBar.setBackgroundColor(mContext.getResources().getColor(R.color.task_open));
                break;
            case 2:
                taskStatusBar.setBackgroundColor(mContext.getResources().getColor(R.color.task_in_progress));
                break;
            case 3:
                taskStatusBar.setBackgroundColor(mContext.getResources().getColor(R.color.task_completed));
                break;
            case 4:
                taskStatusBar.setBackgroundColor(mContext.getResources().getColor(R.color.task_closed));
                break;
        }

        return null;
    }

    @Override
    public void toggle(boolean active) {
        expandTaskIMG.setImageResource(active ? R.drawable.collapse_item : R.drawable.expand_item);
    }

    @Override
    public int getContainerStyle() {
        return R.style.TreeNodeStyleCustom;
    }

//I was relying on this class first for my nodes, then I just used the existing Task class that I have

//    public static class TaskTreeItem {
//        public String taskName;
//        public String projectName;
//        public String startdate;
//        public String endDate;
//        public int taskStatusId;
//
//        public TaskTreeItem(String taskName, String projectName, String startDate, String endDate, int taskStatusId) {
//            this.taskName = taskName;
//            this.projectName = projectName;
//            this.startdate = startDate;
//            this.endDate = endDate;
//            this.taskStatusId = taskStatusId;
//        }
//    }
}

Seems fine? thanks again

bmelnychuk commented 9 years ago

Well... your method public View createNodeView returns null. That is not correct

Odaym commented 9 years ago

well now I'm embarrassed, ok that was it, I was able to see the tree now. As far as this issue goes, totally closed, appreciate the prompt reply

Odaym commented 9 years ago

Just wanna say again, the way you wrote the algorithm again was the solution..thanks for 2 things now, didnt know the algorithm for adding the children was wrong even

bmelnychuk commented 9 years ago

You are welcome!