MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

深度分析:android-thinkmap-treeview

项目背景与痛点

在移动应用开发领域,树状视图(Tree View)和思维导图(Mind Map)的应用十分广泛。对于展示复杂层次结构的数据,这些视图能够直观地展现数据关系,便于用户理解和操作。而现存的开源组件往往功能有限,无法满足复杂场景的需求。正是为了解决这一问题,guaishouN/android-thinkmap-treeview 应运而生。该项目提供了一个自定义视图组件,能够渲染复杂的树状图、思维导图以及组织结构图,同时还支持拖拽、节点合并删除等功能,极大地提升了用户体验。

核心技术揭秘

在技术实现层面,android-thinkmap-treeview 采用了自定义视图(Custom View)技术,通过重写 View 的 onDraw 方法来绘制节点和连接线。此外,项目还引入了数据模型的概念,每个节点都可以被定义为一个具有多个属性的对象,包括节点名称、子节点列表、位置信息等。通过这种方式,可以灵活地配置视图的表现形式。

下面通过一张 Mermaid 图表,展示其数据流逻辑:

graph TD A[用户交互] --> B[触发事件处理] B --> C{"处理模型数据"} C -->|"更新数据模型"| D[执行布局算法] C -->|"未更新"| E[跳过重绘] D --> F[重绘节点] F --> G[渲染视图]

功能亮点与差异

与其他树状图组件相比,android-thinkmap-treeview 的亮点在于以下几点:

  1. 灵活的节点管理:节点可以动态添加、删除和更新,支持自定义节点样式和交互逻辑。
  2. 多级联动:支持多级子节点的嵌套显示,用户可以通过展开或折叠操作来控制所关注的层次信息。
  3. 定制化配置:不仅节点样式可配置,整体视图的展示方式也可以按需定制,如树状图、思维导图等。

这些功能使得 android-thinkmap-treeview 适用于多种复杂业务场景,提供了更为丰富的功能和更高的灵活性。

应用场景与落地建议

此项目适用于任何需要展示复杂层次数据结构的应用场景,比如组织结构图展示、家庭树等关系图、知识体系图(思维导图)以及业务流程图等。尽管其功能强大,但在实际应用中也需要注意一些细节:

  1. 性能优化:由于节点多且复杂,视图渲染过程中可能会消耗较多资源,建议在性能敏感的场景中进行适当的优化,比如懒加载内容。
  2. 事件处理:节点的交互事件处理应尽量简洁高效,避免阻塞主线程。

综合评价

android-thinkmap-treeview 作为一个功能丰富且灵活的自定义组件,能够很好地解决复杂层次图展示的问题。其强大的自定义能力和多级联动功能使得它不仅适用于展示复杂数据结构,也适合用在各种需要直观展现信息关系的应用场景下。然而,项目的灵活性也带来了一定的性能负担,需要开发者在使用过程中根据具体需求进行相应优化。

尽管存在一些性能上的考量,但得益于其简化且强大的特性,android-thinkmap-treeview 依然不失为开发复杂层次图的优秀选择。

语言占比

Java

Release

贡献者

README

GysoTreeView

【中文】【English】 ⭐If ok, give me a star⭐

⭐⭐⭐⭐⭐Tree View; Mind map; Think map; tree map; 树状图;思维导图;组织机构图;层次图;树型图

A custom tree view for Android, designed for easy drawing some tree nodes (e.g. thind mind and tree nodes). Includes smoothly zoom, move, limit and center fix animation support, and allows easy extension so you can add your own child node’s customs view and touch event detection.

    dependencies {
//请直接使用lib中的代码,1.0.0这个引用库很久没有更新了
    	implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
   	implementation 'io.github.guaishoun:gyso-treeview:1.0.1'
   }

Funtions

  • 🍇Smoothly zoom, move
  • 🍈Fix your window view port
  • 🍉Custom your subview for special node
  • 🍊Custom lines between nodes
  • 🍋Dynamic remove nodes
  • 🍌Dynamic add nodes
  • 🥭Drag to rebuild the nodes’ relationship

Releases & downloads

Base–Line, LayoutManger, Custom node view

Add

Remove

Drag Edit Mode

Click

Zoom and Fit Window

Steps for use
    <com.gyso.treeview.GysoTreeView
        android:id="@+id/base_tree_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorBackground">
    </com.gyso.treeview.GysoTreeView>

Before presentation, Animal class means you own bean class, like this:

public class Animal {
    public int headId;
    public String name;
}

To use a tree view, you should do 5 steps as follows:

  1. Customs adapter by extends TreeViewAdapter.

    public class AnimalTreeViewAdapter extends TreeViewAdapter<Animal> {
        private DashLine dashLine =  new DashLine(Color.parseColor("#F06292"),6);
        @Override
        public TreeViewHolder<Animal> onCreateViewHolder(@NonNull ViewGroup viewGroup, NodeModel<Animal> node) {
            //TODO in inflate item view
            NodeBaseLayoutBinding nodeBinding = NodeBaseLayoutBinding.inflate(LayoutInflater.from(viewGroup.getContext()),viewGroup,false);
            return new TreeViewHolder<>(nodeBinding.getRoot(),node);
        }
    
        @Override
        public void onBindViewHolder(@NonNull TreeViewHolder<Animal> holder) {
            //TODO get view and node from holder, and then control your item view
            View itemView = holder.getView();
            NodeModel<Animal> node = holder.getNode();
    		...
        }
    
        @Override
        public Baseline onDrawLine(DrawInfo drawInfo) {
            // TODO If you return an BaseLine, line will be draw by the return one instead of TreeViewLayoutManager's
    		// if(...){
            //   ...
            // 	 return dashLine;
       		// }
            return null;
        }
    }
    
  2. configure layout manager. Space unit is dp. You can custom you line by extends {@link com.gyso.treeview.line.BaseLine}

    int space_50dp = 50;
    int space_20dp = 20;
    //choose a demo line or a customs line. StraightLine, PointedLine, DashLine, SmoothLine are available.
    Baseline line =  new DashLine(Color.parseColor("#4DB6AC"),8);
    //choose layoout manager. VerticalTreeLayoutManager,RightTreeLayoutManager are available.
    TreeLayoutManager treeLayoutManager = new BoxRightTreeLayoutManager(this,space_50dp,space_20dp,line);
    
     // TODO Other stable layout managers like below:
     // new BoxDownTreeLayoutManager(this,space_50dp,space_20dp,line);
     // new BoxLeftTreeLayoutManager(this,space_50dp,space_20dp,line);
     // new BoxUpTreeLayoutManager(this,space_50dp,space_20dp,line);
     // new BoxHorizonLeftAndRightLayoutManager(this,space_50dp,space_20dp,line);
     // new BoxVerticalUpAndDownLayoutManager(this,space_50dp,space_20dp,line);
    
  3. setting adapter and layout manager for your tree view.

    ...
    treeView = findViewById(R.id.tree_view);   
    TreeViewAdapter adapter = new AnimlTreeViewAdapter();
    treeView.setAdapter(adapter);
    treeView.setTreeLayoutManager(treeLayoutManager);
    ...
    
  4. nodes data setting

    //Create a TreeModel by using a root node.
    NodeModel<Animal> node0 = new NodeModel<>(new Animal(R.drawable.ic_01,"root"));
    TreeModel<Animal> treeModel = new TreeModel<>(node0);
    
    //Other nodes.
    NodeModel<Animal> node1 = new NodeModel<>(new Animal(R.drawable.ic_02,"sub0"));
    NodeModel<Animal> node2 = new NodeModel<>(new Animal(R.drawable.ic_03,"sub1"));
    NodeModel<Animal> node3 = new NodeModel<>(new Animal(R.drawable.ic_04,"sub2"));
    NodeModel<Animal> node4 = new NodeModel<>(new Animal(R.drawable.ic_05,"sub3"));
    NodeModel<Animal> node5 = new NodeModel<>(new Animal(R.drawable.ic_06,"sub4"));
    
    
    //Build the relationship between parent node and childs,like:
    //treeModel.add(parent, child1, child2, ...., childN);
    treeModel.add(node0, node1, node2);
    treeModel.add(node1, node3, node4);
    treeModel.add(node2, node5);
    
    //finally set this treeModel to the adapter
    adapter.setTreeModel(treeModel);
    
  5. If your want to edit your tree view, please use an editor.

final TreeViewEditor editor = binding.baseTreeView.getEditor();

//add nodes
NodeModel<Animal> a = new NodeModel<>(new Animal(R.drawable.ic_13,"add-" + atomicInteger.getAndIncrement()));
NodeModel<Animal> b = new NodeModel<>(new Animal(R.drawable.ic_10,"add-" + atomicInteger.getAndIncrement()));
NodeModel<Animal> c = new NodeModel<>(new Animal(R.drawable.ic_11,"add-" + atomicInteger.getAndIncrement()));
editor.addChildNodes(targetNode,a,b,c);

//remove node
editor.removeNode(toRemoveNode);

//view center in window viewport
editor.focusMidLocation()
    
//drag to move and build new relationship
editor.requestMoveNodeByDragging(isChecked);
Notes & limitations

Firstly, only vertical-down derection layout and right direction layout is available, more layout style should be code.

Secondly, customing lines by extends BaseLine may be a little complicate for Android beginner, and performance issues will happen if you using carefully.

Finally, this custom view will be continuely improved, if you has some innovative ideas, please tell me. Thanks for you patience.

I will tell you how it works on my CSDN blogs.Thx.

Star History

Star History Chart

评论

暂无评论