自定义布局之树形布局(七):分支数限制

上一篇讲解了树形布局拖拽效果的实现,到上一篇为止树形布局的功能就基本实现了。本篇从树的分支这个角度来对树形布局的代码进行优化。

思路解析

以三叉树为例,三叉树所有结点的分支数都在0~3这个范围内。某结点有三个分支,如果再插入一个子结点就破坏了三叉树的定义。

在树形布局里,我们也可以给它添加这样的检查机制,使之成为严格的n叉树,在运行的时候如果破坏了这种分支数限制就抛出异常,这样就可以让开发者严格遵守n叉树的规则了。

基本实现

首先先定义分支数属性。

<resources>
    <declare-styleable name="TreeView">
        ...
        <attr name="branch" format="integer"/>
    </declare-styleable>
</resources>
private static final int BRENCH_INFINATE = -1;
private int mMaxBranch;

private void init(Context context,AttributeSet attrs){
		...
        mMaxBranch = typedArray.getInt(R.styleable.TreeView_branch,BRENCH_INFINATE);
        ...
    }

从代码里可以看出,默认情况下树形布局并没有对分支树进行限制,也就是说它不是一颗n叉树。

接着在定义一个异常类,在n叉树分支规则被破坏时抛出。

private static class TreeException extends RuntimeException{
        public TreeException(String message) {
            super(message);
        }
}

下面是检查分支数的代码。

private void checkBranch(){
        if(mMaxBranch == BRENCH_INFINATE){
            return;
        }

        int branchCount = getChildCount() - 1;

        if(branchCount > mMaxBranch){
            throw new TreeException("this is a " + mMaxBranch + " fork tree,however it's count of branch is " + branchCount);
        }
}

布局类控件可以通过addView方法动态增加子控件,这个方法会调用requestLayout方法,进而触发整个布局重新测量、摆放以及绘制。所以接下来只要在onMeasure方法里调用checkBranch方法就行了。

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        checkBranch();

        measureChildren(widthMeasureSpec,heightMeasureSpec);

       if(mTreeDirection == DIRECTION_LEFT_TO_RIGHT || mTreeDirection == DIRECTION_RIGHT_TO_LEFT){
           measureHorizontal(widthMeasureSpec,heightMeasureSpec);
       }else{
           measureVertical(widthMeasureSpec,heightMeasureSpec);
       }
}

测试

现在在一个二叉树里放三个分支。

<com.pyjtlk.widget.TreeLayout
        android:id="@+id/treeView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#A00"
        app:treeDirection="leftToRight"
        app:branch="2"
        app:levelInterval="50dp">
	
		<!--根结点-->
		<View
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="#A0A"/>
		
		<!--分支结点1-->
		<View
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="#A0A"/>

		<!--分支结点2-->
		<View
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="#A0A"/>

		<!--分支结点3-->
		<View
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="#A0A"/>
</com.pyjtlk.widget.TreeLayout>

果然报错了,三个分支破坏了二叉树的定义。
在这里插入图片描述

最后

对完整代码感兴趣的朋友可以看看Github项目

下一篇讲解Padding支持的优化

参考文章

https://www.jianshu.com/p/a6ea264a07b8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值