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

首頁 > 系統(tǒng) > Android > 正文

Android項(xiàng)目實(shí)戰(zhàn)手把手教你畫圓形水波紋loadingview

2020-04-11 10:56:22
字體:
供稿:網(wǎng)友

本文實(shí)例講解的是如何畫一個(gè)滿滿圓形水波紋loadingview,這類效果應(yīng)用場(chǎng)景很多,比如內(nèi)存占用百分比之類的,分享給大家供大家參考,具體內(nèi)容如下
效果圖如下:

預(yù)備的知識(shí):

  • 1.貝塞爾曲線    如果你不了解,可以來這里進(jìn)行基礎(chǔ)知識(shí)儲(chǔ)備:神奇的貝塞爾曲線
  • 2.Paint.setXfermode()  以及PorterDuffXfermode

千萬不要被這個(gè)b的名字嚇到,不熟悉看到可能會(huì)認(rèn)為很難記,其實(shí) 只要站在巨人的丁丁上 還是很簡單的。
好了 廢話不多說 ,跟我一步步來做一個(gè)炫酷的view吧。

首先給一些屬性,在構(gòu)造器里初始化(不要再ondraw new東西不要再ondraw new東西不要再ondraw new東西不要再ondraw new東西)
 

  //繪制波紋   private Paint mWavePaint;    private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.XOR);//設(shè)置mode 為XOR   //繪制圓   private Paint mCirclePaint;   private Canvas mCanvas;//我們自己的畫布   private Bitmap mBitmap;   private int mWidth;   private int mHeight;    public WaveLoadingView(Context context) {     this(context,null);   }    public WaveLoadingView(Context context, AttributeSet attrs) {     this(context, attrs,0);   }    public WaveLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {     super(context, attrs, defStyleAttr);      mWavePaint = new Paint();     mWavePaint.setColor(Color.parseColor("#33b5e5"));     mCirclePaint = new Paint();     mCirclePaint.setColor(Color.parseColor("#99cc00"));         }   @Override   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {     int widthSize = MeasureSpec.getSize(widthMeasureSpec);     int widthMode = MeasureSpec.getMode(widthMeasureSpec);     int heightSize = MeasureSpec.getSize(heightMeasureSpec);     int heightMode = MeasureSpec.getMode(heightMeasureSpec);     if (widthMode == MeasureSpec.EXACTLY) {       mWidth = widthSize;     }       if (heightMode == MeasureSpec.EXACTLY) {       mHeight = heightSize;     }     setMeasuredDimension(mWidth, mHeight);     mBitmap = Bitmap.createBitmap(300,300, Bitmap.Config.ARGB_8888); //生成一個(gè)bitmap     mCanvas = new Canvas(mBitmap);//講bitmp放在我們自己的畫布上,實(shí)際上mCanvas.draw的時(shí)候 改變的是這個(gè)bitmap對(duì)象   }    

然后,我們給他繪制一點(diǎn)東西,用來介紹PorterDuffXfermode

@Override   protected void onDraw(Canvas canvas) {     mCanvas.drawCircle(100,100,50,mCirclePaint);      mCanvas.drawRect(100,100,200,200,mWavePaint);     canvas.drawBitmap(mBitmap,0,0,null);     super.onDraw(canvas);   } 

嗯,可以看到 是我們現(xiàn)在自己的畫布上鋪了一個(gè)bitmap(這里可以理解canvas為桌子  bitmap為畫紙,我們?cè)赽imap上畫畫), 然后在bitmap上畫了 一個(gè)圓,和一個(gè)矩形。最后把我們的mBitmap畫到系統(tǒng)的畫布上(顯示到屏幕上),得到了以下效果。

然后我們用setXfermode()方法給他設(shè)置一個(gè)mode,這里設(shè)置XOR。

可以發(fā)現(xiàn)! 相交的地方消失了! 是不是很神奇。
在改一個(gè)mode 試試

private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER); 


可以看到 圓形跑到了矩形上面來。  然后巨人給我們總結(jié)各個(gè)模式如了下圖,這里給一個(gè)說明dst為先畫的 src為后畫的:.

大家可以根據(jù)這個(gè)規(guī)律試一下。

現(xiàn)在,我們把圓和矩形重疊。模式去掉。

protected void onDraw(Canvas canvas) {      //dst     mCanvas.drawCircle(150,150,50,mCirclePaint);  /    mWavePaint.setXfermode(mMode);     //src     mCanvas.drawRect(100,100,200,200,mWavePaint);     canvas.drawBitmap(mBitmap,0,0,null);     super.onDraw(canvas);   } 

我的圓怎么沒了。。  其實(shí)圓是被覆蓋掉了。 然后我們想實(shí)現(xiàn)一個(gè)效果,就是在圓的范圍內(nèi),顯示矩形的內(nèi)容,該怎么做呢。自己照著圖找找吧哈哈。

我們要實(shí)現(xiàn)的是一個(gè)圓形的水波紋那種loadingview。。首要就是實(shí)現(xiàn)這個(gè)水波紋。
這時(shí)候貝塞爾曲線就派上用場(chǎng)了。這里采用三階貝塞爾, 不停地改變X 模擬水波效果。

 if (x > 50) {       isLeft = true;     } else if (x < 0) {       isLeft = false;     } <span style="white-space:pre">    </span>if (y > -50) { //大于-50是因?yàn)檩o助點(diǎn)是50 為了讓他充滿整個(gè)屏幕       y--;     }    if (isLeft) {       x = x - 1;     } else {       x = x + 1;     }     mPath.reset();     mPath.moveTo(0, y);     mPath.cubicTo(100 + x*2, 50 + y, 100 + x*2, y-50, mWidth, y);//前兩個(gè)參數(shù)是輔助點(diǎn)     mPath.lineTo(mWidth, mHeight);//充滿整個(gè)畫布     mPath.lineTo(0, mHeight);//充滿整個(gè)畫布     mPath.close(); 

之后用mCanvas來繪制這個(gè)bitmap,要注意的是 繪制之前要清空mBitmap,不然path會(huì)重疊

mBitmap.eraseColor(Color.parseColor("#00000000"));  //dst  mCanvas.drawPath(mPath, mPaint); canvas.drawBitmap(mBitmap, 0, 0, null);       postInvalidateDelayed(10); 

 哈,水波效果出來了。   接著想辦法讓他畫到一個(gè)圓形中。 首先繪制一個(gè)圓

mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint); 

現(xiàn)在讓我們回到剛才的問題,如何在dst的范圍內(nèi)繪制src呢。。。答案是。。SRC_IN 你找對(duì)了嗎。添加模式

//dst    mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint);     mPaint.setXfermode(mMode);    //src    mCanvas.drawPath(mPath, mPaint);     canvas.drawBitmap(mBitmap, 0, 0, null); 

是不是有點(diǎn)感覺了。如果不這樣做 就需要考慮好多問題。動(dòng)態(tài)計(jì)算沿著圓弧x,y坐標(biāo)  計(jì)算arcTo的范圍。

完善一下,添加一個(gè)percent來代表進(jìn)度,讓y來根據(jù)percent動(dòng)態(tài)改變
y = (int) ((1-mPercent /100f) *mHeight); 

添加setPercent方法

public void setPercent(int percent){     mPercent = percent;   } 

畫上百分比的文字。

String str = mPercent + "%";     float txtLength = mTextPaint.measureText(str);     canvas.drawText(mPercent + "%", mWidth / 2-txtLength/2, mHeight / 2, mTextPaint); 

然后配合seekBar,最后改改字體大小  畫筆透明度。 添加個(gè)背景圖 就成了效果圖上的效果。

是不是很有趣,大家可以動(dòng)手實(shí)現(xiàn)一下!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 郑州市| 新昌县| 广河县| 资溪县| 独山县| 铜鼓县| 增城市| 琼海市| 南昌市| 兴海县| 依兰县| 武功县| 尚志市| 姚安县| 崇阳县| 绵阳市| 宁乡县| 道孚县| 茶陵县| 循化| 静宁县| 平利县| 长泰县| 桃园县| 新乡县| 福泉市| 吕梁市| 万宁市| 大关县| 西乌| 收藏| 乳源| 上虞市| 洪洞县| 梁河县| 克东县| 来凤县| 夏津县| 赫章县| 延吉市| 瓮安县|