Android自定义View实现流程节点图

项目需要,需要做一个自上而下的流程节点图,实现过程如下,当然不是最终实现效果;
Android自定义View实现流程节点图_第1张图片

  • 自定义属性

首选在values文件下建一个attrs文件,内容如下


    
        
        
        
        
        
        
        
        
    

  • 选择和设置构造方法;

然后自定义的ProcessView 继承view

  public ProcessView(Context context) {
        this(context, null);
    }

    public ProcessView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);//初始化自定义属性
    }

  • 重写onMeasure()方法
  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(View.MeasureSpec.getSize(widthMeasureSpec), measureSize(1));
    }
  • 重写onDraw()方法
 @Override
    public void onDraw(Canvas canvas) {
        for (int vIndex = 0; vIndex < verticalNum; vIndex++) {
            List list = new ArrayList<>();
            int hNum = Integer.parseInt(horizontalNum[vIndex]);
            // item实际宽度
            int tempWidth = (getWidth() - horizontalSpace * (hNum - 1)) / hNum;

            for (int hIndex = 0; hIndex < hNum; hIndex++) {
                Rect rectBorder = new Rect();
                String str = texts.get(vIndex).get(hIndex);
                rectBorder.top = (vIndex) * itemHeight + (vIndex) * verticalSpace;
                rectBorder.bottom = rectBorder.top + itemHeight;
                if (tempWidth >= itemWidth) {
                    // 距离两边的距离
                    int margin = (getWidth() - (itemWidth * hNum + (hNum - 1) * horizontalSpace)) / 2;
                    rectBorder.left = margin + hIndex * itemWidth + hIndex * horizontalSpace;
                    rectBorder.right = itemWidth + rectBorder.left;
                } else {
                    rectBorder.left = hIndex * tempWidth + hIndex * horizontalSpace;
                    rectBorder.right = tempWidth + rectBorder.left;
                }
                drawContent(canvas, rectBorder, str);
                drawLinkLine(canvas, rectBorder, hNum, vIndex);
                list.add(rectBorder);
            }
            rects.put(vIndex, list);
        }
    }
  • 文字内容

  public HashMap> getTextShow() {
        List text1 = Arrays.asList("执行通知");
        List text2 = Arrays.asList("送达文书");
        List text3 = Arrays.asList("强行措施", "财产调查", "解除措施");
        List text4 = Arrays.asList("查询存款", "搜查", "传唤", "悬赏执行");
        List text5 = Arrays.asList("查明财产");
        List text6 = Arrays.asList("查封", "扣押", "冻结", "扣划", "评估", "拍卖");
        List text7 = Arrays.asList("执行和解", "终本约谈", "自动履行");
        HashMap> map = new HashMap>();
        map.put(0, text1);
        map.put(1, text2);
        map.put(2, text3);
        map.put(3, text4);
        map.put(4, text5);
        map.put(5, text6);
        map.put(6, text7);
        return map;
    }
  • 画文字
 /**
     * 画文字和背景
     */
    private void drawContent(Canvas canvas, Rect rect, String str) {
        canvas.drawRect(rect, paint);
        canvas.drawText(str
                , (rect.right + rect.left) / 2f
                , (rect.bottom + rect.top) / 2f + textHeight / 2 - paint.getFontMetrics().descent
                , paint);
    }
  • 画连线
/***
     * 画连接线
     * @param rect     当前Item的Rect
     * @param currHNum 当前的水平方向 有多少个Item
     * @param vIndex 当前是垂直方向的第几个
     */
    private void drawLinkLine(Canvas canvas, Rect rect, int currHNum, int vIndex) {
        int stopX = getX(rect);
        int startX = getX(rect);

        if (vIndex < verticalNum - 1) {
            //画Item下面一半的垂直连接线
            canvas.drawLine(startX, rect.bottom, stopX, (rect.bottom + verticalSpace / 2f), paint);

            //画水平连接线
            if (currHNum > 1 && lastItemRect != null && lastItemRect.top == rect.top) {
                canvas.drawLine(getX(lastItemRect), (rect.bottom + verticalSpace / 2f), getX(rect), (rect.bottom + verticalSpace / 2f), paint);
            }
        }

        if (vIndex != 0) {
            //画Item上面一半的垂直连接线
            canvas.drawLine(startX, (rect.top - verticalSpace / 2f), stopX, rect.top, paint);

            //画水平连接线
            if (currHNum > 1 && lastItemRect != null && lastItemRect.top == rect.top) {
                canvas.drawLine(getX(lastItemRect), (rect.top - verticalSpace / 2f), getX(rect), (rect.top - verticalSpace / 2f), paint);
            }
        }
        lastItemRect = rect;
    }
  • 布局文件
 

更多效果图见下
Android自定义View实现流程节点图_第2张图片
Android自定义View实现流程节点图_第3张图片
Demo地址https://github.com/shunplus/ProcessView

你可能感兴趣的:(安卓笔记)