上一篇展示了树形布局的效果及使用方法,本篇讲解设计这个树形布局的总体思路及它的自定义属性。
总体思路
1.递归
(作为一个程序员)提到树,相信大家第一时间想到的是数据结构里的各种树(二叉树,哈夫曼树、红黑树等)。树这种数据结构有很强的递归性,遍历树、查询高度等等操作其实都可以递归的方式来实现。简言之就是树—>树的子树—>子树的子树…
利用这种递归的思想,在设计树形布局时我们就可以不必总是担心整棵树的各种变量。关心局部,做好局部就行了(有点像贪心算法)。
本树形布局其实很简单,1号为根结点,2、3、4为子结点,其中2、3、4是线性摆放的。
就这么简单。而4、5、6、7又是一个树形布局,其中4为根结点、5、6、7为子结点。4、5、6、7这个布局(树)就是一个子布局(子树)。
这么设计有什么好处呢?其实可以大大减少测量和摆放实现的难度。如下图,利用递归红色外布局把黄色的子布局看成了一个整体(并不在乎这个子布局内部做了什么,只关心它总体的宽高,只关心结果),如此一来要得到红色布局的高度就容易多了。黄色布局对自己的子树也是这么做的。
2.多方向
下面是我们最最常见的方向----从上到下。
从下到上呢?其实整个布局的尺寸是一样的,只是摆放的方向变了。
水平的树也是一样的。(如果把两棵水平树拼在一起,再重写连接线的实现似乎就可以做出思维导图布局了,这个会在后面的文章中讲到)
3.自定义连接线
如果我们能抽象出一个连接线绘制器类,这样就可以根据自己的需要来绘制连接线了(这个会在后面的文章中讲到)
4.层级间隔
为了能让布局有一定的空间来绘制连接线,这里可以提出一个层级间隔的概念,也就是父节点与下一层节点的一个间隔距离(蓝色和黄色的宽度)。
5.可拖拽
有手画过树结构的朋友应该知道,画一颗6、7层的树往往一下子就会用掉半张纸。的确,树结构会占用大量的显示空间,树的层数多了手机屏幕可就没办法全部显示了。为了能看到树个各个部分,我们需要给这个布局提供拖拽的功能,就像百度地图那样。
自定义属性
想了这么多东西,现在就来声明一下自定义属性。目前能想到的属性是层级间隔、树的方向和拖拽功能。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TreeView">
<attr name="levelInterval" format="dimension"/>
<attr name="treeDirection" format="enum">
<enum name="leftToRight" value="0"/>
<enum name="rightToLeft" value="1"/>
<enum name="upToDown" value="2"/>
<enum name="downToUp" value="3"/>
</attr>
<attr name="locked" format="boolean"/>
</declare-styleable>
</resources>
locked是锁定,解锁时布局就可以拖拽了。
最后
下一篇将讲解树形布局的宽高测量。