简单的自定义横向流程轴

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;

public class CustomView5 extends ViewGroup {

    private static int INDICATOR_LINE_TEXT_SIZE = 4;
    private String indicator_text;
    private int def_radius_color;
    private int small_radius_color;
    private int big_radius_color;
    private float def_radius;
    private float small_def_radius;
    private float big_def_radius;
    private int indicator_def_color;
    private int indicator_select_color;
    private float indicator_text_size;
    private float axis_size;
    private int axis_def_color;
    private int axis_size_select_color;
    private String[] indicator;
    private Paint def_radius_paint;
    private Paint small_radius_paint;
    private Paint big_radius_paint;
    private Paint indicator_def_paint;
    private Paint indicator_select_paint;
    private Paint axis_def_paint;
    private Paint axis_select_paint;
    private String indicator_first_text;
    private String indicator_last_text;
    private float indicator_text_margin_top;
    private int max_text_size;
    private int DEF_INTERVAL = 100;
    private int interval;

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

    public CustomView5(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //
        setWillNotDraw(false);
        //
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView5);
        indicator_text = typedArray.getString(R.styleable.CustomView5_text_indicator);
        def_radius_color = typedArray.getColor(R.styleable.CustomView5_def_radius_color, Color.BLACK);
        small_radius_color = typedArray.getColor(R.styleable.CustomView5_small_radius_color, Color.BLACK);
        big_radius_color = typedArray.getColor(R.styleable.CustomView5_big_radius_color, Color.BLACK);
        def_radius = typedArray.getDimension(R.styleable.CustomView5_def_radius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics()));
        small_def_radius = typedArray.getDimension(R.styleable.CustomView5_small_radius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, getResources().getDisplayMetrics()));
        big_def_radius = typedArray.getDimension(R.styleable.CustomView5_big_radius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 18, getResources().getDisplayMetrics()));
        indicator_text_margin_top = typedArray.getDimension(R.styleable.CustomView5_indicator_text_margin_top, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 18, getResources().getDisplayMetrics()));
        indicator_def_color = typedArray.getColor(R.styleable.CustomView5_indicator_textcolor_def, Color.BLACK);
        indicator_select_color = typedArray.getColor(R.styleable.CustomView5_indicator_textcolor_select, Color.BLACK);
        indicator_text_size = typedArray.getDimension(R.styleable.CustomView5_indicator_textsize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14, getResources().getDisplayMetrics()));
        axis_size = typedArray.getDimension(R.styleable.CustomView5_axis_size, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics()));
        axis_def_color = typedArray.getColor(R.styleable.CustomView5_axis_def_color, Color.BLACK);
        axis_size_select_color = typedArray.getColor(R.styleable.CustomView5_axis_select_color, Color.BLACK);
        typedArray.recycle();
        initPait();
    }

    private void initPait() {
        def_radius_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        def_radius_paint.setColor(def_radius_color);
        //
        small_radius_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        small_radius_paint.setColor(small_radius_color);
        //
        big_radius_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        big_radius_paint.setColor(big_radius_color);
        //
        indicator_def_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        indicator_def_paint.setColor(indicator_def_color);
        indicator_def_paint.setTextSize(indicator_text_size);
        //
        indicator_select_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        indicator_select_paint.setColor(indicator_select_color);
        indicator_select_paint.setTextSize(indicator_text_size);
        //
        axis_def_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        axis_def_paint.setColor(axis_def_color);
        axis_def_paint.setStrokeWidth(axis_size);
        //
        axis_select_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        axis_select_paint.setColor(axis_size_select_color);
        axis_select_paint.setStrokeWidth(axis_size);
        axis_select_paint.setStrokeCap(Paint.Cap.ROUND);
        splitIndicator();
    }

    private void splitIndicator() {
        if (!TextUtils.isEmpty(indicator_text)) {
            indicator = indicator_text.split("#");
            if (indicator.length > 0) {
                indicator_first_text = indicator[0];
                indicator_last_text = indicator[indicator.length - 1];
                for (String s : indicator) {
                    if (s.length() > max_text_size) {
                        max_text_size = s.length();
                    }
                }
            }
        }
    }
     private CircleView[] view;
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width = getMeasuredWidth(widthMode, widthSize);
        int height = getMeasuredHeight(heightMode, heightSize);
        view=new CircleView[indicator.length];
        for (int i=0;i<indicator.length;i++){
            CircleView circleView=new CircleView(getContext(),new CircleView.CircleViewPanit(def_radius,def_radius_paint, small_def_radius,small_radius_paint, big_def_radius,big_radius_paint));
            addView(circleView);
            view[i]=circleView;
        }
        setMeasuredDimension(width, height);
    }
    
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        interval = (int) ((getWidth() - getPaddingRight() - getPaddingLeft() - firstIndicatorTextMarginLeft() - lastIndicatorTextMarginRight()) / (indicator.length - 1));
        //canvas.drawCircle(cx, big_def_radius, def_radius, def_radius_paint);
        for(int i=0;i<view.length;i++){
        int left = (int) ((getPaddingLeft() + firstIndicatorTextMarginLeft() + interval * i)-big_def_radius);
        int top=getPaddingTop();
            view[i].layout(left,top,left+(int) big_def_radius*2,(int) (top+big_def_radius*2));
        }
    }

    private float firstIndicatorTextMarginLeft() {
        float indicator_first_margin_left;
        if (indicator_first_text.length() >= INDICATOR_LINE_TEXT_SIZE) {
            indicator_first_margin_left = indicator_def_paint.measureText(indicator_first_text.substring(0, INDICATOR_LINE_TEXT_SIZE)) / 2;
        } else {
            indicator_first_margin_left = indicator_def_paint.measureText(indicator_first_text.substring(0, indicator_first_text.length()))/2;
        }
        return indicator_first_margin_left;
    }

    private float lastIndicatorTextMarginRight() {
        float indicator_last_margin_right;
        if (indicator_last_text.length() >= INDICATOR_LINE_TEXT_SIZE) {
            indicator_last_margin_right = indicator_def_paint.measureText(indicator_last_text.substring(0, INDICATOR_LINE_TEXT_SIZE)) / 2;
        } else {
            indicator_last_margin_right = indicator_def_paint.measureText(indicator_last_text.substring(0, indicator_last_text.length()))/2;
        }
        return indicator_last_margin_right;
    }

    private int getMeasuredHeight(int heightMode, int heightSize) {
        int height = 0;
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            int lines = 0;
            if (max_text_size % INDICATOR_LINE_TEXT_SIZE > 0) {
                lines = max_text_size / INDICATOR_LINE_TEXT_SIZE + 1;
            } else {
                lines = max_text_size / INDICATOR_LINE_TEXT_SIZE;
            }
            height = (int) (getPaddingTop() + big_def_radius * 2 + rowTextHeight() * lines + indicator_text_margin_top + getPaddingBottom());
        }
        return height;
    }

    private int rowTextHeight() {
        indicator_def_paint.setTextSize(indicator_text_size);
        Paint.FontMetrics fontMetrics = indicator_def_paint.getFontMetrics();
        return (int) Math.ceil((fontMetrics.bottom - fontMetrics.top));
    }

    private int getMeasuredWidth(int widthMode, int widthSize) {
        int width = 0;
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            if (indicator.length > 0) {
                width = (int) (getPaddingLeft() + getPaddingRight() + firstIndicatorTextMarginLeft() + lastIndicatorTextMarginRight() + DEF_INTERVAL * (indicator.length - 1));
            }
        }
        return width;
    }
    private  boolean drawDef=true;
    @Override
    protected void onDraw(Canvas canvas) {
        drawAxis(canvas);
        drawCircle(canvas);
        drawText(canvas);

    }

    private void drawCircle(Canvas canvas) {
        for (int i=0;i<view.length;i++){
            if(i<=currentStep){
                view[i].drawExcircle(true);
            }
        }
    }

    private void drawText(Canvas canvas) {
        for (int i = 0; i < indicator.length; i++) {
            Paint paint;
            if(i<=currentStep){
                paint=indicator_select_paint;
            }else{
                paint=indicator_def_paint;
            }
            float cx = getPaddingLeft() + firstIndicatorTextMarginLeft() + (interval * i);
            //
            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            float startY = big_def_radius * 2 +indicator_text_margin_top+ rowTextHeight() - fontMetrics.descent;
            //
            int text_length = indicator[i].length();
            int lines;
            if (text_length % INDICATOR_LINE_TEXT_SIZE > 0) {
                lines = text_length / INDICATOR_LINE_TEXT_SIZE + 1;
                for (int j = 0; j < lines; j++) {
                    if (INDICATOR_LINE_TEXT_SIZE * (j + 1) > text_length) {
                        float line_text_with = paint.measureText(indicator[i].substring(INDICATOR_LINE_TEXT_SIZE * j, text_length));
                        canvas.drawText(indicator[i].substring(INDICATOR_LINE_TEXT_SIZE * j, text_length), cx - line_text_with / 2, startY + rowTextHeight() * j , paint);
                    } else {
                        float line_text_with = paint.measureText(indicator[i].substring(INDICATOR_LINE_TEXT_SIZE * j, INDICATOR_LINE_TEXT_SIZE * (j + 1)));
                        canvas.drawText(indicator[i].substring(INDICATOR_LINE_TEXT_SIZE * j, INDICATOR_LINE_TEXT_SIZE * (j + 1)), cx - line_text_with / 2, startY + rowTextHeight() * j, paint);
                    }
                }
            } else {
                lines = text_length / INDICATOR_LINE_TEXT_SIZE;
                for (int k = 0; k < lines; k++) {
                    float line_text_with = paint.measureText(indicator[i].substring(INDICATOR_LINE_TEXT_SIZE * k, INDICATOR_LINE_TEXT_SIZE * (k + 1)));
                    canvas.drawText(indicator[i].substring(INDICATOR_LINE_TEXT_SIZE * k, INDICATOR_LINE_TEXT_SIZE * (k + 1)), cx - line_text_with / 2, startY + rowTextHeight() * k, paint);
                }
            }
        }

    }

    private void drawAxis(Canvas canvas) {
        canvas.drawLine(getCenterCircleX(), big_def_radius, getWidth() - getPaddingRight() - lastIndicatorTextMarginRight(), big_def_radius, axis_def_paint);
        canvas.drawLine(getCenterCircleX(), big_def_radius, getCenterCircleX()+currentStep*interval, big_def_radius, axis_select_paint);
    }

    private float getCenterCircleX() {
        return firstIndicatorTextMarginLeft() + getPaddingLeft();
    }
    private int currentStep=0;
    public void currentStep(int currentStep) {
        if(currentStep>=1 && currentStep<=indicator.length){
            this.currentStep=currentStep-1;
            invalidate();
        }else{
            throw new IndexOutOfBoundsException("没哟这一步呀,,,");
        }
    }
}  
 
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;



public class CircleView extends View {
    private CircleViewPanit panits;
    private Camera camera;
    private Matrix matrix;
    public CircleView(Context context, CircleViewPanit panit) {
        super(context);
        this.panits = panit;
        camera = new Camera();
        matrix = new Matrix();
    }

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

    }

    private boolean def = true;
    private boolean drawExcircle=false;
    public void drawExcircle(boolean drawExcircle){
        this.drawExcircle=drawExcircle;
        invalidate();
    }
    private final static int FPS = 1000 / 60;
    private int degrees=0;
    @Override
    protected void onDraw(Canvas canvas) {
        float cx=getWidth()/2;
        float cy=getHeight()/2;
        if (def) {
            def = false;
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, panits.getDef_radius(), panits.getDef_paint());
        }
        if(drawExcircle){
            
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, panits.getBig_def_radius(), panits.getBig_radius_paint());
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, panits.getSmall_def_radius(), panits.getSmall_radius_paint());
            //3D动画 TODO
            
         /*   camera.save();
            camera.rotateZ(degrees);

            camera.getMatrix(matrix);
            camera.restore();
            //
            matrix.preTranslate(-cx,-cy);
            matrix.postTranslate(cx,cy);
            //
            canvas.setMatrix(matrix);
            //

          
            canvas.drawArc(new RectF(0,0,cx*2,cy*2),0,10,true,panits.getSmall_radius_paint());
            canvas.drawArc(new RectF(0,0,cx*2,cy*2),120,10,true,panits.getSmall_radius_paint());
            canvas.drawArc(new RectF(0,0,cx*2,cy*2),240,10,true,panits.getSmall_radius_paint());
            //
            degrees+=20;
            postInvalidateDelayed(FPS);*/
        }

    }

    public static class CircleViewPanit {
        private float def_radius;
        private Paint def_paint;
        private float small_def_radius;
        private Paint small_radius_paint;
        private float big_def_radius;
        private Paint big_radius_paint;

        public CircleViewPanit(float def_radius, Paint def_paint, float small_def_radius, Paint small_radius_paint, float big_def_radius, Paint big_radius_paint) {
            this.def_radius = def_radius;
            this.def_paint = def_paint;
            this.small_def_radius = small_def_radius;
            this.small_radius_paint = small_radius_paint;
            this.big_def_radius = big_def_radius;
            this.big_radius_paint = big_radius_paint;
        }

        public float getDef_radius() {
            return def_radius;
        }

        public void setDef_radius(float def_radius) {
            this.def_radius = def_radius;
        }

        public Paint getDef_paint() {
            return def_paint;
        }

        public void setDef_paint(Paint def_paint) {
            this.def_paint = def_paint;
        }

        public float getSmall_def_radius() {
            return small_def_radius;
        }

        public void setSmall_def_radius(float small_def_radius) {
            this.small_def_radius = small_def_radius;
        }

        public Paint getSmall_radius_paint() {
            return small_radius_paint;
        }

        public void setSmall_radius_paint(Paint small_radius_paint) {
            this.small_radius_paint = small_radius_paint;
        }

        public float getBig_def_radius() {
            return big_def_radius;
        }

        public void setBig_def_radius(float big_def_radius) {
            this.big_def_radius = big_def_radius;
        }

        public Paint getBig_radius_paint() {
            return big_radius_paint;
        }

        public void setBig_radius_paint(Paint big_radius_paint) {
            this.big_radius_paint = big_radius_paint;
        }
    }
}
 
<declare-styleable name="CustomView5">
    <attr name="text_indicator" format="string"></attr>
    <attr name="def_radius" format="dimension"></attr>
    <attr name="def_radius_color" format="color"></attr>
    <attr name="small_radius" format="dimension"></attr>
    <attr name="small_radius_color" format="color"></attr>
    <attr name="big_radius" format="dimension"></attr>
    <attr name="big_radius_color" format="color"></attr>
    <attr name="indicator_text_margin_top" format="dimension"></attr>
    <attr name="indicator_textsize" format="dimension"></attr>
    <attr name="indicator_textcolor_def" format="color"></attr>
    <attr name="indicator_textcolor_select" format="color"></attr>
    <attr name="axis_def_color" format="color"></attr>
    <attr name="axis_select_color" format="color"></attr>
    <attr name="axis_size" format="dimension"></attr>
</declare-styleable>
<com.example.cameracustomview.CustomView5
    android:id="@+id/custom5"
    android:layout_marginTop="20dp"
    android:paddingRight="8dp"
    android:paddingLeft="8dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:text_indicator="五一啦五一啦五一啦五一啦五一啦五一啦#吃饭吃饭吃饭吃饭吃饭吃饭吃饭吃饭吃饭吃饭#干啥干啥干啥干啥干啥干啥干啥干啥干啥#豆豆豆豆豆豆豆豆豆豆豆豆豆豆#球球球球球球球球球球球球球球球球球"
    app:axis_def_color="#aaaaaa"
    app:axis_size="4dp"
    app:axis_select_color="#288AFC"
    app:def_radius="6dp"
    app:def_radius_color="#aaaaaa"
    app:small_radius="8dp"
    app:small_radius_color="#288AFC"
    app:big_radius="12dp"
    app:big_radius_color="#fff"
    app:indicator_text_margin_top="10dp"
    app:indicator_textsize="15sp"
    app:indicator_textcolor_def="#000000"
    app:indicator_textcolor_select="#288AFC"
    />


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过自定义布局和绘制来实现一个横向时间。以下是一个简单的示例: 1. 创建一个自定义的视图类,继承自 View。 ```java public class TimelineView extends View { private List<String> events; // 存储时间上的事件列表 public TimelineView(Context context) { super(context); init(); } public TimelineView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public TimelineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { events = new ArrayList<>(); // 初始化事件列表 events.add("事件1"); events.add("事件2"); events.add("事件3"); // ... } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); // 绘制时间的线 Paint linePaint = new Paint(); linePaint.setColor(Color.RED); linePaint.setStrokeWidth(5); canvas.drawLine(0, height / 2, width, height / 2, linePaint); // 绘制时间上的事件 Paint textPaint = new Paint(); textPaint.setColor(Color.BLACK); textPaint.setTextSize(30); int eventCount = events.size(); int eventSpacing = width / (eventCount + 1); // 事件之间的间距 for (int i = 0; i < eventCount; i++) { float xPos = eventSpacing * (i + 1); float yPos = height / 2; canvas.drawText(events.get(i), xPos, yPos, textPaint); } } } ``` 2. 在你的布局文件中使用自定义的 TimelineView。 ```xml <com.example.timeline.TimelineView android:layout_width="match_parent" android:layout_height="100dp" /> ``` 请注意,上述代码只是一个基本示例,你可以根据自己的需求进行扩展和美化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值