Android 自定义节点流程View

在做项目的过程中原型图里画了一个这样的UI,请看下图:这里写图片描述这里写图片描述
实现这个UI其实也不难,直接在XML布局里面也可以实现,就是麻烦一点。但是根据我们公司的产品经理的设计思路,肯定不能画死的,所以我想还是用代码画出来,不限制只有三个节点流程(目前只有三个节点流程)。
有了需求咱们就该想思路,我的思路是获取当前view的宽度,对比当前的宽度分为八个圆点(如果你想圆点与圆点之间的间隔短一点那就多分几个),然后计算文字的宽度相对于圆点的剧中位置,得到位置之后就改画了。在画完第一个之后进入for循环继续画出第二个点。逻辑有点不清楚还是直接看代码吧!

public class LineView extends View {

private int mRoundLeft = 50;
private int mRoundRight = 70;
private int mRoundTop = 130;
private int mRoundBottom = 170;
private int mRoundSize = 20;//圆的直径
private Paint mPaint;
private TextPaint tp;
private int mAlphaRoundSize = 30;//透明圆直径
private int tag;

private String[] text_name = {"发起","审批中","完成"};

public LineView(Context context) {
    super(context);
}

public LineView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    onRund(canvas);
}

public void setData(int tag){
    this.tag = tag;
}

private void onRund(Canvas canvas) {

//获取控件宽度、高度
int height = getHeight();
int width = getWidth();

    int win_heightcenter = height / 4;//view的高度的四分之一
    int mRoundHeight = height - win_heightcenter;//圆距离顶部的位置
    int mRroundSize = mRoundSize / 2;//圆的半径


    mRoundTop = mRoundHeight-mRroundSize;//圆的顶部位置
    mRoundBottom = mRoundHeight+mRroundSize;//圆的底部位置

    int width_item = width / 8;//宽度分成八个流程节点每个流程节点对应的宽度
    mRoundLeft = width_item - mRroundSize;//圆点左边对应对左边的边距
    mRoundRight = width_item + mRroundSize;//圆点右边对应左边的边距



    mPaint = new Paint();
    Paint mLinePaint = new Paint();

// canvas.drawRect(110,10,210,110,mPaint);

// 定义一个矩形

// 画圆

    int mLineTopBootom = mRoundTop + (mRoundBottom - mRoundTop)/2;

    tp = new TextPaint();


    for (int a = 0;a<3;a++){

// 设置文字大小
tp.setTextSize(height/3);
//文字字体加粗
tp.setFakeBoldText(true);

        mLinePaint.setStrokeWidth(5);//笔宽5像素
        if(tag==0){
            if(a==0||a==1){
                mPaint.setColor(Color.parseColor("#056eb4"));
                tp.setColor(Color.parseColor("#056eb4"));
            }else{
                mPaint.setColor(Color.parseColor("#c1c1c1"));
                tp.setColor(Color.parseColor("#c1c1c1"));
            }
            if(a==0){
                mLinePaint.setColor(Color.parseColor("#056eb4"));
            }else{
                mLinePaint.setColor(Color.parseColor("#c1c1c1"));
            }
        }else{
            mLinePaint.setColor(Color.parseColor("#c1c1c1"));
            tp.setColor(Color.parseColor("#c1c1c1"));
            mPaint.setColor(Color.parseColor("#c1c1c1"));
        }

// 计算文字的宽度
int textWidth = getTextWidth(tp, text_name[a]);

        Log.i("TAG", "文字宽度: "+textWidth);

// 画圆
RectF rf2 = new RectF(mRoundLeft, mRoundTop, mRoundRight, mRoundBottom);
canvas.drawOval(rf2, mPaint);
// 计算圆的中心点得到文字X轴的位置
int i = mRoundRight - (mRoundRight - mRoundLeft) /2 ;//圆的中心点
int t = i - textWidth / 2;//文字X位置
// 绘制文字
canvas.drawText(text_name[a],t,mRoundHeight - mRoundSize , tp);

        if(a != 2) {

// 绘制线
canvas.drawLine(mRoundRight, mLineTopBootom, mRoundRight + 200, mLineTopBootom, mLinePaint);
}
// 透明圆
if(tag==0){
if(a==1){
mPaint.setAlpha(100);
RectF rf3 = new RectF(mRoundLeft-5, mRoundTop-5, mRoundRight+5, mRoundBottom+5);
canvas.drawOval(rf3, mPaint);
}
}else{
if(a==2){
mPaint.setAlpha(100);
RectF rf3 = new RectF(mRoundLeft-5, mRoundTop-5, mRoundRight+5, mRoundBottom+5);
canvas.drawOval(rf3, mPaint);
}
}

// 下一个节点的位置
mRoundRight = mRoundRight + 200;
mRoundLeft = mRoundLeft + 200;

        mPaint.reset();
        tp.reset();

// tp.setColor(Color.RED);
// mPaint.setColor(Color.GRAY);
}
}
// 计算文字宽度
public static int getTextWidth(Paint paint, String str) {
int iRet = 0;
if (str != null && str.length() > 0) {
int len = str.length();
float[] widths = new float[len];
paint.getTextWidths(str, widths);
for (int j = 0; j < len; j++) {
iRet += (int) Math.ceil(widths[j]);
}
}
return iRet;
}

}

代码里我写了一个公共方法setData(int tag),传入0和1,是用来控制当前显示第几个节点的。因为当前项目里面只用到三个节点,我就把三个节点的名字写死了,放在数组里面,当然你们也可以写一个公共的方法,set进去。
在使用的时候直接在代码里使用当前View就行了,但是不要忘了要实现setData方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值