1. 程式人生 > >android: 一次自繪控制元件的體驗

android: 一次自繪控制元件的體驗

一個盆友在 qq 上面給我一個截圖,問我有沒有見過這種效果。我一看,貌似不太難,雖然我並不熟悉自定義控制元件,但是網上的教程很多,於是決定實現一下。

原效果圖

這個就是給我的截圖。不是很清晰,也不完整。但是重點突出出來了。

於是,我看了看 HenCoder 的教程1,決定實現一下。(當然,實現期間,也翻閱了一下其他人的部落格)

我實現的效果如下:

這裡寫圖片描述

大體實現貼一下:

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        this.mWidth = w;
        this.mHeight = h;

        min
= Math.min(mWidth, mHeight); tableList = DynamicData.getViewSource(); paint = new Paint(); LogUtils.w(tableList); oval = new RectF(0, 0, min, min); icon = new RectF(); diffLeft = min / 10; diffRight = diffLeft; } @Override protected void onDraw(Canvas canvas
) { super.onDraw(canvas); drawLeft(canvas); iconLength = 1f * min / 17; int height = (int) (iconLength / 2); for (Table t : tableList) { float left = min + diffLeft; float right = left + iconLength; float top = 0; float
bottom = top + iconLength; paint.setColor(t.color); icon.set(left, height + top, right, height + bottom); canvas.drawRect(icon, paint); paint.setTextSize(iconLength); paint.setColor(Color.BLACK); canvas.drawText(t.name + "\t" + (int) t.percent + "%", right + diffRight, height + bottom, paint); height += iconLength * 3; } } private void drawLeft(Canvas canvas) { paint.setColor(Color.parseColor("#dbdbdb")); canvas.drawRect(oval, paint); int start = 180; for (Table t : tableList) { float angle = (float) t.percent / 100 * 360; paint.setColor(t.color); paint.setStrokeCap(Paint.Cap.ROUND); scaleOval(t.scale); canvas.drawArc(oval, start, angle, true, paint); start += angle; } paint.setColor(Color.WHITE); canvas.drawCircle(1f * min / 2, 1f * min / 2, min * 1f / 12, paint); scaleOval(1); // 要加這一句,不然 onStop 後再進來就變小了 } private void scaleOval(float scale) { oval.set(0, 0, min, min); float left = 1f * min * (1 - scale) / 2; float top = 1f * min * (1 - scale) / 2; float right = 1f * min * scale + left; float bottom = 1f * min * scale + top; oval.set(left, top, right, bottom); }

嗯,裡面的邏輯不復雜,主要是對系統 api 的呼叫,然後計算一下,每次畫的起始位置。

其實,這種東西,我之前看到也會害怕,但是,真的很一般,不難的。

不過,這裡還是有需要優化的地方,比如最小尺寸,如果設定成 wrap_conent 怎麼處理,等等。我這裡的邏輯全部是 onDraw()需要的,其他的,我沒有去實現。