自定义View之状态显示

需求

项目中为了显示当前订单的状态

效果图

自定义View实现代码

public class StateView extends View {

    private int mCircularColor;

    private int mImageColor;

    private int mTextColor;

    private int mRadius;

    private int mState;

    float radius;//圆的半径

    int progress = 0;//进度

    RectF arcRectF = new RectF();

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);


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

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

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StateView);
        mCircularColor = typedArray.getInteger(R.styleable.StateView_circular_color, Color.RED);
        mImageColor = typedArray.getInteger(R.styleable.StateView_image_color, Color.WHITE);
        mTextColor = typedArray.getInteger(R.styleable.StateView_text_color, Color.WHITE);
        mRadius = typedArray.getInteger(R.styleable.StateView_radius, 80);
        mState = typedArray.getInteger(R.styleable.StateView_state, 1);
        typedArray.recycle();//回收
        radius = dpToPixel(mRadius);
    }

    public StateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    {
        paint.setTextSize(dpToPixel(40));
        //paint.setTextAlign(Paint.Align.CENTER);//设置文本居中对齐
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    public void stareAnimal() {
        final ObjectAnimator animator = ObjectAnimator.ofInt(this, "progress", 0, 440);
        animator.setDuration(1500);
        animator.setInterpolator(new FastOutSlowInInterpolator());
        animator.start();
    }

    public void setState(int state) {
        this.mState = state;
    }

    /**
     * 为了使用动画来控制进度
     */
    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }

    /**
     * 为了使用动画来控制进度
     */


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

        float centerX = getWidth() / 2;
        float centerY = getHeight() / 2;

        if (progress > 360) {
            //画一个红色的圆在底部
            paint.setColor(mCircularColor);
            paint.setStyle(Paint.Style.FILL);
            paint.setStrokeCap(Paint.Cap.ROUND);
            canvas.drawCircle(centerX, centerY, radius, paint);

            //画一个黑色的圆逐渐缩小
            paint.setColor(Color.WHITE);
            paint.setStyle(Paint.Style.FILL);
            paint.setStrokeCap(Paint.Cap.ROUND);
            float reduce = dpToPixel(progress - 360);
            canvas.drawCircle(centerX, centerY, radius - reduce, paint);

            Path path = new Path();
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(mImageColor);
            paint.setPathEffect(new CornerPathEffect(5));//画线的路径效果,CornerPathEffect可以将路径的转角变得圆滑

            if (progress == 440) {//画一个√
                switch (mState) {
                    case 0:
                        path.moveTo(centerX - dpToPixel(45), centerY - dpToPixel(0));
                        path.lineTo(centerX - dpToPixel(20), centerY + dpToPixel(30)); // 由当前位置 (0, 0) 向 (100, 100) 画一条直线
                        path.rLineTo(dpToPixel(60), -dpToPixel(50));
                        canvas.drawPath(path, paint);
                        break;
                    case 1:
                        //画×
                        canvas.drawLine(centerX - dpToPixel(30), centerY - dpToPixel(30), centerX + dpToPixel(30), centerY + dpToPixel(30), paint);
                        canvas.drawLine(centerX + dpToPixel(30), centerY - dpToPixel(30), centerX - dpToPixel(30), centerY + dpToPixel(30), paint);
                        break;
                    case 2:
                        //画!
                        canvas.drawLine(centerX, centerY - dpToPixel(40), centerX, centerY + dpToPixel(20), paint);
                        //画点
                        paint.setStrokeCap(Paint.Cap.ROUND);
                        canvas.drawPoint(centerX, centerY + dpToPixel(50), paint);
                        break;
                }
            }

        } else {//360度以下

            //画一个圆弧
            paint.setColor(mCircularColor);
            paint.setStyle(Paint.Style.STROKE);//空心
            paint.setStrokeCap(Paint.Cap.ROUND);//设置画笔笔刷类型 影响画笔始末端
            paint.setStrokeWidth(dpToPixel(15));

            arcRectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
            canvas.drawArc(arcRectF, 0, progress, false, paint);//画圆弧

            //绘制需要显示的文字
            paint.setColor(mTextColor);
            paint.setStyle(Paint.Style.FILL);
            // 计算Baseline绘制的起点X轴坐标 ,计算方式:画布宽度的一半 - 文字宽度的一半
            String text = (int) progress + "%";
            int baseX = (int) (canvas.getWidth() / 2 - paint.measureText(text) / 2);
            //int baseX = (int) (centerX);
            // 计算Baseline绘制的Y坐标 ,计算方式:画布高度的一半 - 文字总高度的一半
            int baseY = (int) (centerY - ((paint.descent() + paint.ascent()) / 2));

            canvas.drawText(text, baseX, baseY, paint);
        }

    }

    public static float dpToPixel(float dp) {
        DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
        return dp * metrics.density;
    }
}

自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="StateView">
        <!--圆形背景颜色-->
        <attr name="circular_color" format="color" />
        <!--圆形中图案颜色-->
        <attr name="image_color" format="color" />
        <!--进度字体颜色-->
        <attr name="text_color" format="color" />
        <!--圆的半径-->
        <attr name="radius" format="dimension" />
        <!--状态-->
        <attr name="state">
            <enum name="complete" value="0" />
            <enum name="failure" value="1" />
            <enum name="warning" value="2" />
        </attr>
    </declare-styleable>
</resources>

使用

   <com.example.roczheng.customview.view.StateView
        android:id="@+id/state"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_gravity="center_horizontal"
        app:circular_color="@color/colorAccent"
        app:image_color="#ffffff"
        app:state="failure"
        app:text_color="@color/colorPrimary" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值