Git Product home page Git Product logo

androidtreeview's Introduction

This project is deprecated. You can still use it as it. Let me know if someone is interested in supporting it.

AndroidTreeView

Recent changes

2D scrolling mode added, keep in mind this comes with few limitations: you won't be able not place views on right side like alignParentRight. Everything should be align left. Is not enabled by default

Description

Tree view implementation for android

Android Arsenal

Demo

AndroidTreeView Demo on Google Play Store

Features

    1. N - level expandable/collapsable tree
    1. Custom values, views, styles for nodes
    1. Save state after rotation
    1. Selection mode for nodes
    1. Dynamic add/remove node

Known Limitations

  • For Android 4.0 (+/- nearest version) if you have too deep view hierarchy and with tree its easily possible, your app may crash


Integration

1) Add library as a dependency to your project

compile 'com.github.bmelnychuk:atv:1.2.+'

2) Create your tree starting from root element. TreeNode.root() element will not be displayed so it doesn't require anything to be set.

TreeNode root = TreeNode.root();

Create and add your nodes (use your custom object as constructor param)

 TreeNode parent = new TreeNode("MyParentNode");
 TreeNode child0 = new TreeNode("ChildNode0");
 TreeNode child1 = new TreeNode("ChildNode1");
 parent.addChildren(child0, child1);
 root.addChild(parent);

3) Add tree view to layout

 AndroidTreeView tView = new AndroidTreeView(getActivity(), root);
 containerView.addView(tView.getView());

The simplest but not styled tree is ready. Now you can see parent node as root of your tree

4) Custom view for nodes

Extend TreeNode.BaseNodeViewHolder and overwrite createNodeView method to prepare custom view for node:

public class MyHolder extends TreeNode.BaseNodeViewHolder<IconTreeItem> {
    ...
    @Override
    public View createNodeView(TreeNode node, IconTreeItem value) {
        final LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.layout_profile_node, null, false);
        TextView tvValue = (TextView) view.findViewById(R.id.node_value);
        tvValue.setText(value.text);
        
        return view;
    }
    ...
    public static class IconTreeItem {
        public int icon;
        public String text;
    }
}

5) Connect view holder with node

  IconTreeItem nodeItem = new IconTreeItem();
  TreeNode child1 = new TreeNode(nodeItem).setViewHolder(new MyHolder(mContext));

6) Consider using

TreeNode.setClickListener(TreeNodeClickListener listener);
AndroidTreeView.setDefaultViewHolder
AndroidTreeView.setDefaultNodeClickListener
...

For more details use sample application as example

Let me know if i missed something, appreciate your support, thanks!

Projects using this library

Blue Dot : World Chat

androidtreeview's People

Contributors

allonmj avatar bmelnychuk avatar mathiasberwig avatar szigetipeter avatar yehe01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androidtreeview's Issues

consider changing the root view to linear layout

I had to use two tree views on the same page, so I needed a root scroll view. I ended up changing the treeview to use a linear layout as the root. That way the user has flexibility in the placement of it.

If you have steps to reproduce this bug (ideally with the sample app, or a screenshot): #4

I can try it out and see if it fixes that too.

Rtl support

First, I would like to thank you for such a valuable work ! ... well down !

second, there is a problem with RtL (Right to Left) in the library which is on devices with RTL language, with the 2d scrolling mode, tree goes outside of the screen if you scroll to left !

Custom icons

Hello sir,
I want to use my own custom icons, but it's now showing. Any suggestion ?

restore state issue

Right now on restoring the code takes the selected nodes and puts them in a hashset

final Set<String> openNodes = new HashSet<>(Arrays.asList(openNodesArray));

So if you have 1;0:0;2;0:0 gives you HashSet {1, 0:0, 2}
but if you have 1;0:0;2 that gives you the same HashSet {1, 0:0, 2}

There is data loss here because there is no indication which 0:0 is selected

To see this in practice go to "Custom Holder Example"
open "My Profile" -> Social
open "Bruce Wayne" -> Social
open "Barry Allen" -> Social; open "Barry Allen" -> Places
rotate the device
All the places nodes are expanded.

I have a solution which looks like this and writes the tree with DFS as a string

    private void getSaveState(TreeNode root, StringBuilder sBuilder) {
        for (TreeNode node : root.getChildren()) {
            if (node.isExpanded()) {
                sBuilder.append(NODE_EXPANDED);
            }
            else {
                sBuilder.append(NODE_COLLAPSED);
            }
            getSaveState(node, sBuilder);
        }
    }

    public String getSaveState() {
        final StringBuilder builder = new StringBuilder();
        getSaveState(mRoot, builder);
        return builder.toString();
    }

Let me know what you think of this solution, and I'll make a pull request with the changes.

Folder structure example

When you expand the tree structure beyond some level it wont scroll horizontally. Only vertical scroll is working. How do I fix this

Use With Picasso

How can I use this superb lib. with Picasso for dynamic Image Loading in th App from URL ???
Plz do rply as quick as possible..!!!

Padding Issue

No Space as in Image for Folder Structure before icon...

Detect what part of a node has been clicked

Is it possible to detect which part of a node has been clicked? I want to have an arrow on the left that expands the node and text to the right that opens a fragment when it's tapped.

how to redraw a node?

Hi,

In my implementation, user can remove a node only when it is a leaf, so I have decided to use:

if(node.isLead()) { btnDelete.setVisibility(View.VISIBLE);}

in createNodeView()

everything works fine, until user decides to delete a branch, so he/she starts to hit delete from the leaf, if all leaves get deleted, technically their parent is now a leaf and should be able to be deleted, on the other hand, in the createNodeView time, it wass not a leaf hence no btnDelete is VISIBLE.
any idea on how can I make the button visible now?
I personally think a node.getParent().forceReDraw() in TreeView.removeNode(node) method would be awesome!

Default animation takes too long if the parent has too many children

Current default animation has no upper time limit to complete. It is taking too long if the selected node has too many children. Is there any way to modify the animation outside the library? I tried subclassing the androidtreeview class and implementing it myself but I had little success.

intention should will be default behavior

this project is cooool!
but first time, i can not know how to intent sub-item,
after search i see this:
v.setDefaultContainerStyle(R.style.TreeNodeStyleCustom);
it works for me,
but i think this should be by default.

How to Hide Nodes Instead of Removing?

I would like to hide nodes, but keep them so they are easy to return.

Also how do you invalidate, or make the AndroidTreeView rebuild / redraw?

The use case is: When the user selects a checkbox / node, some other filters (checkboxes) fall away. But when the use deselects the checkbox's return.

When I load the data, I save the original tree.

TreeNode root = new TreeNode(....);

TreeNode origRoot = root;

I then use tvView.removeNode(node);

I don't want to remove nodes, I just want to hide them, then make them all reappear at once.

@bmelnychuk let me know if this is possible or if it makes sense

No way to change root node

Hello, I can't find a way to change the root node (replace the whole tree). How can this be achieved?

Custom Click listener for Nodes with no child

I used your library to create my own application. I have nodes in root. Out of those three, only one has children. I wanted to know how to handle click events on the nodes that don't have children.

Root:

  • Home
  • Products
    • Product 1
    • Product 2
  • About

Pls show me how to handle click events on Home and About.

change node text or icon

HI,
How can i change a node's text or icon ? I Had change the nodevalue,but the node text doesn't change.
((IconTreeItem)aNode.getValue()).text = "something changed";
Is there method called refreshNodeValue or something?
thanks.

[Question] TreeView in fragment

I used to have my TreeView created in the main Activity. I move it to a Fragment but now nothing show up. I followed your samples but i can't find my mistake. I hope you can help me.

Here is my Fragment creation:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.content_main, null, false);
        mViewRoot = (ViewGroup) view.findViewById(R.id.main_container);

        final TreeNode root = TreeNode.root();
        root.addChild(new TreeNode(new IconTreeItemHolder.IconTreeItem(R.string.ic_home, "Room")));
        atView = new AndroidTreeView(getActivity(), root);
        mViewRoot.addView(atView.getView());

        return view;
    }

And here is my fragment layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/main_container"></RelativeLayout>


</RelativeLayout>

The fragment is added in the actvity xml layout.

Thanks for help.

Same TreeNode ID issue when deleting and inserting nodes

Let's say my root node has three children.
N1: id 0, N2: id 1, N3: id 2
I delete N2 from the tree view, but afterwards N3 still has id 2.
N1: id 0, N3: id 2
Now when I insert a new TreeNode N4, it will be given id 2.
N1: id 0, N3: id 2, N4: id 2

Delete all view Child when expand node make program slow

Why expand a node, we must delete all view child and add again? If that, it's slowly:

    final TreeNode.BaseNodeViewHolder parentViewHolder = getViewHolderForNode(node);
    parentViewHolder.getNodeItemsView().removeAllViews();
    parentViewHolder.toggle(true);

    for (final TreeNode n : node.getChildren()) {
        addNode(parentViewHolder.getNodeItemsView(), n);

        if (n.isExpanded() || includeSubnodes) {
            expandNode(n, includeSubnodes);
        }
    }
     ......................

I only set visible all child when expand node, it's faster:

   node.setExpanded(true);
    final TreeNode.BaseNodeViewHolder parentViewHolder = getViewHolderForNode(node);
    parentViewHolder.toggle(true);

    if (mUseDefaultAnimation) {
        expand(parentViewHolder.getNodeItemsView());
    } else {
        parentViewHolder.getNodeItemsView().setVisibility(View.VISIBLE);
    }

config for proguard

when i enable proguard my app getting crashed, what is the right config for this lib?

Implement selectable background

I need to display a background when I select a node like select element of ListView, I'm trying to set a background in nodeClickListener but doesn't work, any way to solve this? Thanks.

Clear a node's children

Hi,

My main tree got couple of main nodes, and a node which contains the last used leafs.
so whenever the fragment containing the treeView reloads I need to clear the last used node and repopulate it with my logic.

the problem is when I do a foreach loop on treenode.getChildren() and call treeNode.deleteChild(tNode); I get java.util.ConcurrentModificationException

any idea on how to do this ?

I also tried to remove the treeNode itself and re add it, but it is a bit buggy, because the re added node, although is not expanded in the UI, but for the first time, it needs two touches to get expanded.

Listner for Expansing & Collapsing

How can we have Listener or method for checking weather Node is Expanded Or Collapsed ??
Or can we have Listener for that ??
And then How can I add dynamically Add Node & remove all those added node on Collapsing Node ??

Strange treeView.getView() returns null

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

performance issue

when i open a node with many childs, it's take too long to open.
Can we resolve this problem ?

allowBackup:true set in Library?

Hi,

I'm running into a problem where my app has

 <application android:allowBackup="false" tools:replace="allowBackup" />

There seems to be a Gradle/Android bug that causes that to fail because the AndroidTreeView Library has

 <application android:allowBackup="true" /> 

Is there a reason this is set in the library manifest file itself? I was thinking maybe it wasn't necessary?

Thanks for the great software!

Remove the default listener and handle Node expansion manually

I have tried to do treeView.setDefaultNodeClickListener(null); and then do this code whenever I'm creating a new node:

taskNode.setClickListener(new TreeNode.TreeNodeClickListener() {
            @Override
            public void onClick(TreeNode treeNode, Object o) {
                Intent openTaskDetails_Activity = new Intent(getActivity(), Task_ViewPager_Activity.class);
                openTaskDetails_Activity.putExtra(Constants.GOD_TASK_OBJECT, Parcels.wrap(parentTask));
                startActivity(openTaskDetails_Activity);
            }
        });

But when I do this, both actions happen; The node expands/collapses and the item opens in a new activity, how can I disable the default node listener so that I can let the arrow button on the far right of my layout be responsible for expanding and collapsing items?

How to move a node

How can I move a node from a position to another position and let me know if this is possible ?

Number of views increases as user expand more nodes.

The only chance that subviews are removed is in expandNode where new views will be added again.
That means even when user collapse a node, all the subviews are still retained in memory and won't be garbage-collected.

LongClickListener and indenting

Hi,

Thanks for the great library!

an issue I came across today is that my TreeView was doing well until I add LongClickListener to nodes using TreeNode#setLongClickListener();
after this, the direct child of the said Node, would not follow the indenting

any workaround?!

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.