国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

自定義View

2019-11-09 17:16:18
字體:
供稿:網(wǎng)友

自定義View步驟

構(gòu)造函數(shù) 初始化(初始化畫筆Paint)onMeasure 測(cè)量View的大小(暫時(shí)不用關(guān)心)onSizeChanged 確定View大小(記錄當(dāng)前View的寬高)onLayout 確定子View布局(無子View,不關(guān)心)onDraw 實(shí)際繪制內(nèi)容(繪制餅狀圖)

提供接口 提供接口(提供設(shè)置數(shù)據(jù)的接口)

操作類型 API 備注
繪制顏色 drawColor, drawRGB, drawARGB 使用單一顏色填充整個(gè)畫布
繪制基本形狀 drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc 依次為 點(diǎn)、線、矩形、圓角矩形、橢圓、圓、圓弧
繪制圖片 drawBitmap, drawPicture 繪制位圖和圖片
繪制文本 drawText, drawPosText, drawTextOnPath 依次為 繪制文字、繪制文字時(shí)指定每個(gè)文字位置、根據(jù)路徑繪制文字
繪制路徑 drawPath 繪制路徑,繪制貝塞爾曲線時(shí)也需要用到該函數(shù)
頂點(diǎn)操作 drawVertices, drawBitmapMesh 通過對(duì)頂點(diǎn)操作可以使圖像形變,drawVertices直接對(duì)畫布作用、 drawBitmapMesh只對(duì)繪制的Bitmap作用
畫布剪裁 clipPath, cliPRect 設(shè)置畫布的顯示區(qū)域
畫布快照 save, restore, saveLayerXxx, restoreToCount, getSaveCount 依次為 保存當(dāng)前狀態(tài)、 回滾到上一次保存的狀態(tài)、 保存圖層狀態(tài)、 回滾到指定狀態(tài)、 獲取保存次數(shù)
畫布變換 translate, scale, rotate, skew 依次為 位移、縮放、 旋轉(zhuǎn)、錯(cuò)切
Matrix(矩陣) getMatrix, setMatrix, concat 實(shí)際上畫布的位移,縮放等操作的都是圖像矩陣Matrix, 只不過Matrix比較難以理解和使用,故封裝了一些常用的方法。

示例:

1.自定義扇形圖:

通過設(shè)置數(shù)據(jù)名字和數(shù)據(jù)值自動(dòng)生成對(duì)應(yīng)的扇形分析圖。

cv_01 主要繪制算法:

if (null == mData) return; float currentStartAngle = mStartAngle; canvas.translate(mWidth/2, mHeight/2); float r = (float) (Math.min(mHeight,mWidth)/2*0.8); RectF rect = new RectF(-r,-r,r,r); for (int i = 0; i< mData.size(); i++){ CircleData data = mData.get(i); mPaint.setColor(data.getColor()); canvas.drawArc(rect,currentStartAngle,data.getAngle(),true,mPaint); currentStartAngle += data.getAngle(); // 平移畫布 mCenterX = (float) ((float)0.5 * r * Math.cos(Math.toRadians(currentStartAngle - 0.5 * data.getAngle()))); mCenterY = (float) ((float)0.5 * r * Math.sin(Math.toRadians(currentStartAngle - 0.5 * data.getAngle()))); canvas.translate(mCenterX,mCenterY); // 文字中心坐標(biāo) // 設(shè)置字體顏色 mPaint.setColor(Color.BLACK); mPaint.setTextSize(30f); mPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText(decimalFormat.format(data.getPercentage()*100)+" %",0,0,mPaint); canvas.translate(-mCenterX,-mCenterY);//繪制文字完成回到原點(diǎn) }

這里需要特別注意扇形圖中文字的繪制,通過獲取每一個(gè)扇形的夾角以及半徑,不斷的移動(dòng)畫布,從而來獲取文字的繪制位置。 github地址:https://github.com/zoky2017/CustomViewDemo

2.示例2 自定義載入條

cv_02 此定義View是通過網(wǎng)上的自定義載入條改編而來 從效果上看,我們需要考慮以下幾個(gè)問題:

1.葉子的隨機(jī)產(chǎn)生;

2.葉子隨著一條正余弦曲線移動(dòng);

3.葉子在移動(dòng)的時(shí)候旋轉(zhuǎn),旋轉(zhuǎn)方向隨機(jī),正時(shí)針或逆時(shí)針;

4.葉子遇到進(jìn)度條,似乎是融合進(jìn)入;

5.葉子不能超出最左邊的弧角;

7.葉子飄出時(shí)的角度不是一致,走的曲線的振幅也有差別,否則太有規(guī)律性,缺乏美感;

難點(diǎn)在于載入條的橢圓形的填充及葉子對(duì)象飄落軌跡的繪制。

private void drawProgressAndLeafs(Canvas canvas) { if (mProgress >= TOTAL_PROGRESS) { mProgress = 0; } // mProgressWidth為進(jìn)度條的寬度,根據(jù)當(dāng)前進(jìn)度算出進(jìn)度條的位置 mCurrentProgressPosition = mProgressWidth * mProgress / TOTAL_PROGRESS; // 即當(dāng)前位置在圖中所示1范圍內(nèi) 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 // 這個(gè)層級(jí)進(jìn)行繪制能讓葉子感覺是融入棕色進(jìn)度條中 // 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) { // 繪制葉子--根據(jù)葉子的類型和當(dāng)前時(shí)間得出葉子的(x,y) getLeafLocation(leaf, currentTime); // 根據(jù)時(shí)間計(jì)算旋轉(zhuǎn)角度 canvas.save(); // 通過Matrix控制葉子旋轉(zhuǎn) 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); // 通過時(shí)間關(guān)聯(lián)旋轉(zhuǎn)角度,則可以直接通過修改LEAF_ROTATE_TIME調(diào)節(jié)葉子旋轉(zhuǎn)快慢 float rotateFraction = ((currentTime - leaf.startTime) % mLeafRotateTime) / (float) mLeafRotateTime; int angle = (int) (rotateFraction * 360); // 根據(jù)葉子旋轉(zhuǎn)方向確定葉子旋轉(zhuǎn)角度 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

3.挖個(gè)坑,后面補(bǔ)上~


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 庆元县| 伊川县| 龙州县| 大埔区| 青田县| 武乡县| 乌拉特后旗| 昌黎县| 隆回县| 全南县| 林口县| 林芝县| 冷水江市| 冀州市| 南陵县| 墨玉县| 义马市| 和龙市| 含山县| 凤山县| 贡山| 武夷山市| 望谟县| 长顺县| 库车县| 原阳县| 长汀县| 衡阳市| 内黄县| 高雄市| 焦作市| 读书| 乌拉特前旗| 大悟县| 武宁县| 青州市| 沐川县| 合川市| 克拉玛依市| 西昌市| 札达县|