一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android項目實戰手把手教你畫圓形水波紋loadingview

Android項目實戰手把手教你畫圓形水波紋loadingview

2021-05-14 15:20菜雞wing Android

這篇文章主要介紹了Android項目實戰手把手教你畫圓形水波紋loadingview,感興趣的小伙伴們可以參考一下

本文實例講解的是如何畫一個滿滿圓形水波紋loadingview,這類效果應用場景很多,比如內存占用百分比之類的,分享給大家供大家參考,具體內容如下
效果圖如下:

Android項目實戰手把手教你畫圓形水波紋loadingview

預備的知識:

  • 1.貝塞爾曲線    如果你不了解,可以來這里進行基礎知識儲備:神奇的貝塞爾曲線
  • 2.paint.setxfermode()  以及porterduffxfermode

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//繪制波紋
private paint mwavepaint; 
private porterduffxfermode mmode = new porterduffxfermode(porterduff.mode.xor);//設置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); //生成一個bitmap
  mcanvas = new canvas(mbitmap);//講bitmp放在我們自己的畫布上,實際上mcanvas.draw的時候 改變的是這個bitmap對象
}

然后,我們給他繪制一點東西,用來介紹porterduffxfermode

?
1
2
3
4
5
6
7
8
@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);
  }

嗯,可以看到 是我們現在自己的畫布上鋪了一個bitmap(這里可以理解canvas為桌子  bitmap為畫紙,我們在bimap上畫畫), 然后在bitmap上畫了 一個圓,和一個矩形。最后把我們的mbitmap畫到系統的畫布上(顯示到屏幕上),得到了以下效果。

然后我們用setxfermode()方法給他設置一個mode,這里設置xor。

Android項目實戰手把手教你畫圓形水波紋loadingview

可以發現! 相交的地方消失了! 是不是很神奇。
在改一個mode 試試

?
1
private porterduffxfermode mmode = new porterduffxfermode(porterduff.mode.dst_over);

Android項目實戰手把手教你畫圓形水波紋loadingview

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

Android項目實戰手把手教你畫圓形水波紋loadingview

大家可以根據這個規律試一下。

現在,我們把圓和矩形重疊。模式去掉。

?
1
2
3
4
5
6
7
8
9
10
11
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);
  }

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

我們要實現的是一個圓形的水波紋那種loadingview。。首要就是實現這個水波紋。
這時候貝塞爾曲線就派上用場了。這里采用三階貝塞爾, 不停地改變x 模擬水波效果。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (x > 50) {
      isleft = true;
    } else if (x < 0) {
      isleft = false;
    }
<span style="white-space:pre">    </span>if (y > -50) { //大于-50是因為輔助點是50 為了讓他充滿整個屏幕
      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);//前兩個參數是輔助點
    mpath.lineto(mwidth, mheight);//充滿整個畫布
    mpath.lineto(0, mheight);//充滿整個畫布
    mpath.close();

之后用mcanvas來繪制這個bitmap,要注意的是 繪制之前要清空mbitmap,不然path會重疊

?
1
2
3
4
5
6
7
8
9
mbitmap.erasecolor(color.parsecolor("#00000000"));
 
//dst
 mcanvas.drawpath(mpath, mpaint);
 
canvas.drawbitmap(mbitmap, 0, 0, null);
 
 
    postinvalidatedelayed(10);

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

?
1
mcanvas.drawcircle(mwidth / 2, mheight / 2, mwidth / 2, msrcpaint);

現在讓我們回到剛才的問題,如何在dst的范圍內繪制src呢。。。答案是。。src_in 你找對了嗎。添加模式

?
1
2
3
4
5
6
7
8
//dst
   mcanvas.drawcircle(mwidth / 2, mheight / 2, mwidth / 2, msrcpaint);
 
   mpaint.setxfermode(mmode);
   //src
   mcanvas.drawpath(mpath, mpaint);
 
   canvas.drawbitmap(mbitmap, 0, 0, null);

是不是有點感覺了。如果不這樣做 就需要考慮好多問題。動態計算沿著圓弧x,y坐標  計算arcto的范圍。

完善一下,添加一個percent來代表進度,讓y來根據percent動態改變
y = (int) ((1-mpercent /100f) *mheight); 

添加setpercent方法

?
1
2
3
public void setpercent(int percent){
    mpercent = percent;
  }

畫上百分比的文字。

?
1
2
3
string str = mpercent + "%";
    float txtlength = mtextpaint.measuretext(str);
    canvas.drawtext(mpercent + "%", mwidth / 2-txtlength/2, mheight / 2, mtextpaint);

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

是不是很有趣,大家可以動手實現一下!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91麻豆精品国产91久久久 | 国产麻豆视频 | 果冻传媒 天美 麻豆 | 强迫高h | bl高h荡肉古代np | 91天堂在线 | 国产精品成人网红女主播 | 免费看日韩 | 韩国美女主播在线 | 欧美三级小说 | 国外成品精品1688 | 亚洲精品国产成人 | 免费一级毛片在线播放放视频 | 精品免费久久久久久影院 | 欧美最猛性xxxxx男男 | 免费一级片在线 | 美国一级大黄大色毛片 | 美女脱了内裤让男生尿囗 | 色老板最新网站视频地址 | 天天综合天天影视色香欲俱全 | 久久香蕉电影 | 国产香蕉97碰碰在线视频 | 国产精品永久免费自在线观看 | 日韩激情视频在线观看 | 亚洲国产在线视频精品 | 欧美成人手机 | 好大好硬抽搐好爽想要 | 91精品久久国产青草 | 日本不卡在线一区二区三区视频 | 亚洲高清视频网站 | 亚洲日本va午夜中文字幕 | 久久国产精品永久免费网站 | a级影视| 亚偷熟乱区视频在线观看 | 午夜国产小视频 | 特级非洲黑人一级毛片 | 糖心视频在线观看 | 男生操女生动态图 | 99视频在线看 | 九九大香尹人视频免费 | 水多多www视频在线观看高清 |