美文网首页
流程状态图

流程状态图

作者: 有点健忘 | 来源:发表于2018-02-23 17:44 被阅读20次

效果图如下:


image.png

仿这个写的,偷了3张图,至于这里的代码还没看过。看到效果图就先自己写个,以后有空再去看作者咋写的。
https://gitee.com/tangbuzhi/stepview/

代码如下:
定义个抽象类,用来显示状态信息的

public abstract class ShowTextParent {

    public abstract String getShowText();
}

实现类

public class FlowStepData extends ShowTextParent{
    private String des;
    
    public FlowStepData(String des) {
        super();
        this.des = des;
    }
    @Override
    public String getShowText() {
        return des;
    }
}

主要类,字体颜色,线条颜色都是写死的,需要的话再添加对外的方法修改。
另外3种状态图片可以通过设置declare-styleable属性来在布局文件里设置比较方便,偷懒了没写。上边的线条颜色,文字颜色也可以通过declare-styleable来设置。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Align;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import bean.ShowTextParent;

public class FlowStepShow extends View {

    public FlowStepShow(Context context, AttributeSet attrs) {
        super(context, attrs);
        initSomeThing();
    }

    private boolean bottomText = true;// 文字是否在底部显示,默认在底部
    private boolean clickable = true;// 是否可选择
    private int checkedPosition;// 默认的选中位置
    private Paint paintLine = new Paint();
    private Paint paintText = new Paint();
    private int textHeight;
    private int drawablePadding = 5;
    private Bitmap bitmap1, bitmap2, bitmap3;

    private void initSomeThing() {
        paintText.setTextSize(20);
        paintText.setColor(Color.WHITE);
        paintText.setTextAlign(Align.CENTER);
        Rect bounds = new Rect();
        paintText.getTextBounds("您好", 0, 2, bounds);
        textHeight = bounds.height();
        bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_passed);
        bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_target);
        bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_normal);

    }

    ArrayList<ShowTextParent> data = new ArrayList<ShowTextParent>();
    private int lineY;
    private int textY;
    private int length;
    private int interval;

    public void setClick(boolean click) {
        clickable = click;
        postInvalidate();
    }

    public void setData(List<ShowTextParent> lists, int position) {
        data.clear();
        data.addAll(lists);
        if(position>=0&&position<data.size()) {
            checkedPosition = position;
        }else {
            checkedPosition=0;
        }
        postInvalidate();
    }

    public void setData(List<ShowTextParent> lists) {
        setData(lists, 0);
    }

    public void setData(ShowTextParent[] arr, int position) {
        setData(Arrays.asList(arr), position);
    }

    public void setData(ShowTextParent[] arr) {
        setData(arr, 0);
    }

    public void setTextBottom(boolean bottom) {
        bottomText = bottom;
        postInvalidate();
    }

    public int getCheckedPosition() {
        return checkedPosition;
    }

    public void setCheckedPosition(int checkedPosition) {
        if (checkedPosition != this.checkedPosition) {
            this.checkedPosition = checkedPosition;
            postInvalidate();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(),
                textHeight * 2 + drawablePadding + getPaddingTop() + getPaddingBottom());
    }

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

        lineY = getPaddingTop() + textHeight / 2;
        textY = getPaddingTop() + textHeight * 2 + drawablePadding;
        if (!bottomText) {
            lineY = getPaddingTop() + textHeight + drawablePadding + textHeight / 2;
            textY = getPaddingTop() + textHeight;
        }
        length = data.size();
        if (length > 0) {
            interval = (getWidth() - getPaddingLeft() - getPaddingRight()) / length;
            for (int i = 0; i < data.size(); i++) {
                int x = interval / 2 + interval * i;
                canvas.drawText(data.get(i).getShowText(), x, textY, paintText);

                Bitmap bitmap = getBitmap(i);
                canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2, lineY - bitmap.getHeight() / 2, null);
                if (i > 0) {
                    paintLine.setColor(i <= checkedPosition ? Color.WHITE : Color.GRAY);
                    canvas.drawLine(x - interval + getBitmap(i - 1).getWidth() / 2, lineY, x - bitmap.getWidth() / 2,
                            lineY, paintLine);
                }
            }
        }

    }

    private Bitmap getBitmap(int i) {
        if (i < checkedPosition) {
            return bitmap1;
        } else if (i > checkedPosition) {
            return bitmap3;
        } else {
            return bitmap2;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
            if (clickable) {
                int position = getClickPosition(event);
                if (position >= 0) {
                    if (listener != null && position != checkedPosition) {
                        listener.positionChanged(position);
                    }
                    checkedPosition = position;
                    postInvalidate();
                }
            }

            return true;
        }
        return super.onTouchEvent(event);
    }

    private int getClickPosition(MotionEvent event) {
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                int x = interval / 2 + interval * i;
                RectF rect = new RectF(x - 20, lineY - 20, x + 20, lineY + 20);
                if (rect.contains(event.getX(), event.getY())) {
                    return i;
                }
            }
        }
        return -1;
    }

    private StateChangeListener listener;

    public void setListener(StateChangeListener listener) {
        this.listener = listener;
    }

    public interface StateChangeListener {
        public void positionChanged(int position);
    }
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        recycleBitmap(bitmap1);
        recycleBitmap(bitmap2);
        recycleBitmap(bitmap3);
    }
    private void recycleBitmap(Bitmap bitmap) {
        if(bitmap!=null&&!bitmap.isRecycled()) {
            bitmap.recycle();
        }
    }
}

布局文件以及代码中使用

    <widget.FlowStepShow
        android:id="@+id/flowStepShow1"
        android:paddingTop="15dp" 
        android:background="#000"
        android:paddingBottom="15dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <widget.FlowStepShow
        android:id="@+id/flowStepShow2"
        android:paddingTop="5dp" 
        android:paddingBottom="5dp"
        android:background="#000"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


        FlowStepShow flowStepShow=(FlowStepShow) getView().findViewById(R.id.flowStepShow1);
        FlowStepShow flowStepShow2=(FlowStepShow) getView().findViewById(R.id.flowStepShow2);
        ArrayList<ShowTextParent> lists=new ArrayList<ShowTextParent>();
        lists.add(new FlowStepData("下订单"));
        lists.add(new FlowStepData("验证客户订单信息"));
        lists.add(new FlowStepData("支付定金"));
        lists.add(new FlowStepData("订单完成"));
        lists.add(new FlowStepData("已经入住"));
        lists.add(new FlowStepData("已经退房"));
        flowStepShow.setData(lists,3);
        flowStepShow.setListener(new StateChangeListener() {
            
            @Override
            public void positionChanged(int position) {
                System.err.println("current==========="+position);
                
            }
        });
        flowStepShow2.setData(lists,4);
        flowStepShow2.setClick(false);
        flowStepShow2.setTextBottom(false);

抽空修改下,方便在布局文件里设置属性

       <declare-styleable name="FlowStepShowAttr">
           <attr name="flow_step_normal_icon" format="reference"/>
           <attr name="flow_step_target_icon" format="reference"/>
           <attr name="flow_step_passed_icon" format="reference"/>
           <attr name="flow_step_passed_line_color" format="color"/>
           <attr name="flow_step_normal_line_color" format="color"/>
           <attr name="flow_step_text_color" format="color"/>
           <attr name="flow_step_text_size" format="dimension"/>
           <attr name="flow_step_text_bottom" format="boolean"/>
           <attr name="flow_step_clickable" format="boolean"/>
           <attr name="flow_step_drawable_padding" format="dimension"/>
       </declare-styleable>

新的类如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Align;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import bean.ShowTextParent;

public class FlowStepShow extends View {

    public FlowStepShow(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);
        initSomeThing();
    }

    private boolean bottomText = true;// 文字是否在底部显示,默认在底部
    private boolean clickable = true;// 是否可选择
    private int checkedPosition;// 默认的选中位置
    private Paint paintLine = new Paint();
    private Paint paintText = new Paint();
    private int textHeight;
    private int drawablePadding = 5;
    private Bitmap bitmap1, bitmap2, bitmap3;
    private int ic_passed=R.drawable.ic_passed;
    private int ic_target=R.drawable.ic_target;
    private int ic_normal=R.drawable.ic_normal;
    private int textSize=15;
    private int textColor=Color.WHITE;
    private int colorLinePassed=Color.WHITE;
    private int colorLineNormal=Color.GRAY;
    
    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray  typedArray=context.obtainStyledAttributes(attrs, R.styleable.FlowStepShowAttr);
        bottomText=typedArray.getBoolean(R.styleable.FlowStepShowAttr_flow_step_text_bottom, true);
        clickable=typedArray.getBoolean(R.styleable.FlowStepShowAttr_flow_step_clickable, true);
        drawablePadding=typedArray.getDimensionPixelSize(R.styleable.FlowStepShowAttr_flow_step_drawable_padding, 5);
        ic_passed=typedArray.getResourceId(R.styleable.FlowStepShowAttr_flow_step_passed_icon,R.drawable.ic_passed);
        ic_target=typedArray.getResourceId(R.styleable.FlowStepShowAttr_flow_step_target_icon,R.drawable.ic_target);
        ic_normal=typedArray.getResourceId(R.styleable.FlowStepShowAttr_flow_step_normal_icon,R.drawable.ic_normal);
        colorLinePassed=typedArray.getColor(R.styleable.FlowStepShowAttr_flow_step_passed_line_color, Color.WHITE);
        colorLineNormal=typedArray.getColor(R.styleable.FlowStepShowAttr_flow_step_normal_line_color, Color.GRAY);
        
        textColor=typedArray.getColor(R.styleable.FlowStepShowAttr_flow_step_text_color, Color.WHITE);
        textSize=typedArray.getDimensionPixelSize(R.styleable.FlowStepShowAttr_flow_step_text_size, 15);
        typedArray.recycle();
    }
    private void initSomeThing() {
        paintText.setTextSize(textSize);
        paintText.setColor(textColor);
        paintText.setTextAlign(Align.CENTER);
        Rect bounds = new Rect();
        paintText.getTextBounds("您好", 0, 2, bounds);
        textHeight = bounds.height();
        bitmap1 = BitmapFactory.decodeResource(getResources(),ic_passed);
        bitmap2 = BitmapFactory.decodeResource(getResources(), ic_target);
        bitmap3 = BitmapFactory.decodeResource(getResources(), ic_normal);

    }

    ArrayList<ShowTextParent> data = new ArrayList<ShowTextParent>();
    private int lineY;
    private int textY;
    private int length;
    private int interval;

    public void setClick(boolean click) {
        clickable = click;
        postInvalidate();
    }

    public void setData(List<ShowTextParent> lists, int position) {
        data.clear();
        data.addAll(lists);
        if(position>=0&&position<data.size()) {
            checkedPosition = position;
        }else {
            checkedPosition=0;
        }
        
        postInvalidate();
    }

    public void setData(List<ShowTextParent> lists) {
        setData(lists, 0);
    }

    public void setData(ShowTextParent[] arr, int position) {
        setData(Arrays.asList(arr), position);
    }

    public void setData(ShowTextParent[] arr) {
        setData(arr, 0);
    }

    public void setTextBottom(boolean bottom) {
        bottomText = bottom;
        postInvalidate();
    }

    public int getCheckedPosition() {
        return checkedPosition;
    }

    public void setCheckedPosition(int checkedPosition) {
        if (checkedPosition != this.checkedPosition) {
            this.checkedPosition = checkedPosition;
            postInvalidate();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(),
                textHeight * 2 + drawablePadding + getPaddingTop() + getPaddingBottom());
    }

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

        lineY = getPaddingTop() + textHeight / 2;
        textY = getPaddingTop() + textHeight * 2 + drawablePadding;
        if (!bottomText) {
            lineY = getPaddingTop() + textHeight + drawablePadding + textHeight / 2;
            textY = getPaddingTop() + textHeight;
        }
        length = data.size();
        if (length > 0) {
            interval = (getWidth() - getPaddingLeft() - getPaddingRight()) / length;
            for (int i = 0; i < data.size(); i++) {
                int x = interval / 2 + interval * i;
                canvas.drawText(data.get(i).getShowText(), x, textY, paintText);

                Bitmap bitmap = getBitmap(i);
                canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2, lineY - bitmap.getHeight() / 2, null);
                if (i > 0) {
                    paintLine.setColor(i <= checkedPosition ? colorLinePassed: colorLineNormal);
                    canvas.drawLine(x - interval + getBitmap(i - 1).getWidth() / 2, lineY, x - bitmap.getWidth() / 2,
                            lineY, paintLine);
                }
            }
        }

    }

    private Bitmap getBitmap(int i) {
        if (i < checkedPosition) {
            return bitmap1;
        } else if (i > checkedPosition) {
            return bitmap3;
        } else {
            return bitmap2;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
            if (clickable) {
                int position = getClickPosition(event);
                if (position >= 0) {
                    if (listener != null && position != checkedPosition) {
                        listener.positionChanged(position);
                    }
                    checkedPosition = position;
                    postInvalidate();
                }
            }

            return true;
        }
        return super.onTouchEvent(event);
    }

    private int getClickPosition(MotionEvent event) {
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                int x = interval / 2 + interval * i;
                RectF rect = new RectF(x - 20, lineY - 20, x + 20, lineY + 20);
                if (rect.contains(event.getX(), event.getY())) {
                    return i;
                }
            }
        }
        return -1;
    }

    private StateChangeListener listener;

    public void setListener(StateChangeListener listener) {
        this.listener = listener;
    }

    public interface StateChangeListener {
        public void positionChanged(int position);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        recycleBitmap(bitmap1);
        recycleBitmap(bitmap2);
        recycleBitmap(bitmap3);
    }
    private void recycleBitmap(Bitmap bitmap) {
        if(bitmap!=null&&!bitmap.isRecycled()) {
            bitmap.recycle();
        }
    }
}

相关文章

  • React组件生命周期

    问题 理解React组件的生命周期 知识点 React流程状态图 注意:流程状态图为使用React.createC...

  • UML-State Machine Diagram

    流程可以由活动图来表达,要是表示一个事物的某些状态,首选状态图。状态图的元素与活动图类似。 1.状态图的两个状态的...

  • 流程状态图

    效果图如下: 仿这个写的,偷了3张图,至于这里的代码还没看过。看到效果图就先自己写个,以后有空再去看作者咋写的。h...

  • Markdown Mermaid 实用教程

    Mermaid简介 Mermaid 是一个用于画流程图、状态图、时序图、甘特图的库,使用 JS 进行本地渲染,广泛...

  • 供应链Demo

    本文为以服装行业为产品创作供应链管理中WMS模块,含部分原型、流程图、状态图等。

  • mermaid使用指南

    mermaid使用指南 Mermaid 是一个用于画流程图、状态图、时序图、甘特图的库,使用 JS 进行本地渲染,...

  • UML建模之状态图(Statechart Diagram)

    一、状态图简介(Brief introduction) 状态图(Statechart Diagram)主要用于描述...

  • tcp三次握手四次挥手

    tcp三次握手四次挥手 TCP状态图 TCP状态时序图 tcp三次握手 流程图: TCP握手状态说明: TCP_S...

  • uml设计

    如何绘制状态图

  • plantuml-绘制状态图和活动图和部署图​

    背景 状态图:对象的所有状态,以及基于事件发生的状态改变的过程;活动图:用例的工作流程;部署图:系统的软硬件物理体...

网友评论

      本文标题:流程状态图

      本文链接:https://www.haomeiwen.com/subject/pfpxxftx.html