自定義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" />
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章