提供接口 提供接口(提供設置數據的接口)
| 操作類型 | API | 備注 |
|---|---|---|
| 繪制顏色 | drawColor, drawRGB, drawARGB | 使用單一顏色填充整個畫布 |
| 繪制基本形狀 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次為 點、線、矩形、圓角矩形、橢圓、圓、圓弧 |
| 繪制圖片 | drawBitmap, drawPicture | 繪制位圖和圖片 |
| 繪制文本 | drawText, drawPosText, drawTextOnPath | 依次為 繪制文字、繪制文字時指定每個文字位置、根據路徑繪制文字 |
| 繪制路徑 | drawPath | 繪制路徑,繪制貝塞爾曲線時也需要用到該函數 |
| 頂點操作 | drawVertices, drawBitmapMesh | 通過對頂點操作可以使圖像形變,drawVertices直接對畫布作用、 drawBitmapMesh只對繪制的Bitmap作用 |
| 畫布剪裁 | clipPath, cliPRect | 設置畫布的顯示區域 |
| 畫布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次為 保存當前狀態、 回滾到上一次保存的狀態、 保存圖層狀態、 回滾到指定狀態、 獲取保存次數 |
| 畫布變換 | translate, scale, rotate, skew | 依次為 位移、縮放、 旋轉、錯切 |
| Matrix(矩陣) | getMatrix, setMatrix, concat | 實際上畫布的位移,縮放等操作的都是圖像矩陣Matrix, 只不過Matrix比較難以理解和使用,故封裝了一些常用的方法。 |
通過設置數據名字和數據值自動生成對應的扇形分析圖。
主要繪制算法:
這里需要特別注意扇形圖中文字的繪制,通過獲取每一個扇形的夾角以及半徑,不斷的移動畫布,從而來獲取文字的繪制位置。 github地址:https://github.com/zoky2017/CustomViewDemo
此定義View是通過網上的自定義載入條改編而來 從效果上看,我們需要考慮以下幾個問題:
1.葉子的隨機產生;
2.葉子隨著一條正余弦曲線移動;
3.葉子在移動的時候旋轉,旋轉方向隨機,正時針或逆時針;
4.葉子遇到進度條,似乎是融合進入;
5.葉子不能超出最左邊的弧角;
7.葉子飄出時的角度不是一致,走的曲線的振幅也有差別,否則太有規律性,缺乏美感;
難點在于載入條的橢圓形的填充及葉子對象飄落軌跡的繪制。
private void drawProgressAndLeafs(Canvas canvas) { if (mProgress >= TOTAL_PROGRESS) { mProgress = 0; } // mProgressWidth為進度條的寬度,根據當前進度算出進度條的位置 mCurrentProgressPosition = mProgressWidth * mProgress / TOTAL_PROGRESS; // 即當前位置在圖中所示1范圍內 if (mCurrentProgressPosition < mArcRadius) { Log.i(TAG, "mProgress = " + mProgress + "---mCurrentProgressPosition = " + mCurrentProgressPosition + "--mArcProgressWidth" + mArcRadius); // 1.繪制白色ARC,繪制orange ARC // 2.繪制白色矩形 // 1.繪制白色ARC canvas.drawArc(mArcRectF, 90, 180, false, mWhitePaint); // 2.繪制白色矩形 mWhiteRectF.left = mArcRightLocation; canvas.drawRect(mWhiteRectF, mWhitePaint); // 繪制葉子 drawLeafs(canvas); // 3.繪制棕色 ARC // 單邊角度 int angle = (int) Math.toDegrees(Math.acos((mArcRadius - mCurrentProgressPosition) / (float) mArcRadius)); // 起始的位置 int startAngle = 180 - angle; // 掃過的角度 int sweepAngle = 2 * angle; Log.i(TAG, "startAngle = " + startAngle); canvas.drawArc(mArcRectF, startAngle, sweepAngle, false, mOrangePaint); } else { Log.i(TAG, "mProgress = " + mProgress + "---transfer-----mCurrentProgressPosition = " + mCurrentProgressPosition + "--mArcProgressWidth" + mArcRadius); // 1.繪制white RECT // 2.繪制Orange ARC // 3.繪制orange RECT // 這個層級進行繪制能讓葉子感覺是融入棕色進度條中 // 1.繪制white RECT mWhiteRectF.left = mCurrentProgressPosition; canvas.drawRect(mWhiteRectF, mWhitePaint); // 繪制葉子 drawLeafs(canvas); // 2.繪制Orange ARC canvas.drawArc(mArcRectF, 90, 180, false, mOrangePaint); // 3.繪制orange RECT mOrangeRectF.left = mArcRightLocation; mOrangeRectF.right = mCurrentProgressPosition; canvas.drawRect(mOrangeRectF, mOrangePaint); } } /** * 繪制葉子 * * @param canvas */ private void drawLeafs(Canvas canvas) { mLeafRotateTime = mLeafRotateTime <= 0 ? LEAF_ROTATE_TIME : mLeafRotateTime; long currentTime = System.currentTimeMillis(); for (int i = 0; i < mLeafInfos.size(); i++) { Leaf leaf = mLeafInfos.get(i); if (currentTime > leaf.startTime && leaf.startTime != 0) { // 繪制葉子--根據葉子的類型和當前時間得出葉子的(x,y) getLeafLocation(leaf, currentTime); // 根據時間計算旋轉角度 canvas.save(); // 通過Matrix控制葉子旋轉 Matrix matrix = new Matrix(); float transX = mLeftMargin + leaf.x; float transY = mLeftMargin + leaf.y; Log.i(TAG, "left.x = " + leaf.x + "--leaf.y=" + leaf.y); matrix.postTranslate(transX, transY); // 通過時間關聯旋轉角度,則可以直接通過修改LEAF_ROTATE_TIME調節葉子旋轉快慢 float rotateFraction = ((currentTime - leaf.startTime) % mLeafRotateTime) / (float) mLeafRotateTime; int angle = (int) (rotateFraction * 360); // 根據葉子旋轉方向確定葉子旋轉角度 int rotate = leaf.rotateDirection == 0 ? angle + leaf.rotateAngle : -angle + leaf.rotateAngle; matrix.postRotate(rotate, transX + mLeafWidth / 2, transY + mLeafHeight / 2); canvas.drawBitmap(mLeafBitmap, matrix, mBitmapPaint); canvas.restore(); } else { continue; } } }github地址: https://github.com/zoky2017/CustomViewDemo2
新聞熱點
疑難解答