自定义树状图GysoTreeView控件的直角线实现

Posted 怪兽N

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义树状图GysoTreeView控件的直角线实现相关的知识,希望对你有一定的参考价值。

简介

本文主要是在开源树状图GysoTreeView控件上添加直角线实现,丰富原来框架的节点间的画线样式。
github连接: https://github.com/guaishouN/android-tree-view.git
gitee连接:https://gitee.com/guaishoun/gyso_tree_view.git
在这里插入图片描述

实现思想

在fromView中获得起点,在toView中获得终点,然后在使用1/3的父节点与子节点间隙,计算中间直角插值。画线时,主要使用Path的lineTo和moveTo方法,完整代码如下

package com.gyso.treeview.line;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.view.View;

import com.gyso.treeview.adapter.DrawInfo;
import com.gyso.treeview.adapter.TreeViewHolder;
import com.gyso.treeview.cache_pool.PointPool;
import com.gyso.treeview.layout.TreeLayoutManager;
import com.gyso.treeview.model.NodeModel;
import com.gyso.treeview.util.DensityUtils;

/**
* @Author: 怪兽N
* @Time: 2021/5/18  16:47
* @Email: 674149099@qq.com
* @WeChat: guaishouN
* @Describe:
* AngledLine between two nodes
*/
public class AngledLine extends BaseLine {
   public static final int DEFAULT_LINE_WIDTH_DP = 3;
   private int lineColor = Color.parseColor("#055287");
   private int lineWidth = DEFAULT_LINE_WIDTH_DP;
   public AngledLine() {
       super();
   }

   public AngledLine(int lineColor, int lineWidth_dp) {
       this();
       this.lineColor = lineColor;
       this.lineWidth = lineWidth_dp;
   }

   public void setLineColor(int lineColor) {
       this.lineColor = lineColor;
   }

   public void setLineWidth(int lineWidth) {
       this.lineWidth = lineWidth;
   }
   @Override
   public void draw(DrawInfo drawInfo) {
       Canvas canvas = drawInfo.getCanvas();
       TreeViewHolder<?> fromHolder = drawInfo.getFromHolder();
       TreeViewHolder<?> toHolder = drawInfo.getToHolder();
       Paint mPaint = drawInfo.getPaint();
       Path mPath = drawInfo.getPath();
       int layoutType = drawInfo.getLayoutType();
       int spacePeerToPeer = drawInfo.getSpacePeerToPeer();
       int spaceParentToChild = drawInfo.getSpaceParentToChild();

       //get view and node
       View fromView = fromHolder.getView();
       NodeModel<?> fromNode = fromHolder.getNode();
       View toView = toHolder.getView();
       NodeModel<?> toNode = toHolder.getNode();
       Context context = fromView.getContext();

       //set paint
       mPaint.reset();
       mPaint.setColor(lineColor);
       mPaint.setStyle(Paint.Style.STROKE);
       mPaint.setStrokeWidth(DensityUtils.dp2px(context,lineWidth));
       mPaint.setAntiAlias(true);

       //setPath
       mPath.reset();
       if(layoutType== TreeLayoutManager.LAYOUT_TYPE_HORIZON_RIGHT){
           PointF startPoint = PointPool.obtain(fromView.getRight(),(fromView.getTop()+fromView.getBottom())/2f);
           PointF point1 = PointPool.obtain(startPoint.x+spaceParentToChild/3f,startPoint.y);
           PointF endPoint =  PointPool.obtain(toView.getLeft(),(toView.getTop()+toView.getBottom())/2f);
           PointF point2 = PointPool.obtain(startPoint.x+spaceParentToChild/3f,endPoint.y);
           mPath.moveTo(startPoint.x,startPoint.y);
           mPath.lineTo(point1.x,point1.y);
           mPath.lineTo(point2.x,point2.y);
           mPath.lineTo(endPoint.x,endPoint.y);

           //do not forget release
           PointPool.free(startPoint);
           PointPool.free(point1);
           PointPool.free(point2);
           PointPool.free(endPoint);
       }else if(layoutType== TreeLayoutManager.LAYOUT_TYPE_VERTICAL_DOWN){
           PointF startPoint =  PointPool.obtain((fromView.getLeft()+fromView.getRight())/2f,fromView.getBottom());
           PointF point1 = PointPool.obtain(startPoint.x,startPoint.y+spaceParentToChild/3f);
           PointF endPoint =  PointPool.obtain((toView.getLeft()+toView.getRight())/2f,toView.getTop());
           PointF point2 = PointPool.obtain(endPoint.x,startPoint.y+spaceParentToChild/3f);
           mPath.moveTo(startPoint.x,startPoint.y);
           mPath.lineTo(point1.x,point1.y);
           mPath.lineTo(point2.x,point2.y);
           mPath.lineTo(endPoint.x,endPoint.y);

           //do not forget release
           PointPool.free(startPoint);
           PointPool.free(point1);
           PointPool.free(point2);
           PointPool.free(endPoint);
       }else{
           return;
       }

       //draw
       canvas.drawPath(mPath,mPaint);
   }
}

总结

本文内容比较简单,使用Path的lineTo和moveTo方法可以达到目的。

以上是关于自定义树状图GysoTreeView控件的直角线实现的主要内容,如果未能解决你的问题,请参考以下文章

一步步实现这个炫酷的树状节点图自定义控件

一步步实现这个炫酷的树状节点图自定义控件

带 plotly 的树状图 - 如何为层次聚类设置自定义链接方法

echarts 树状图节点自定义图片首次加载不显示的问题

开源Android思维导图控件ThinkMap树状图(类似xMind那种效果)

Qt编写自定义控件41-自定义环形图