手把手教你畫一個 逼格滿滿圓形水波紋loadingview Android

來源:互聯網
上載者:User

手把手教你畫一個 逼格滿滿圓形水波紋loadingview Android

才沒有完結呢o( ̄︶ ̄)n 。大家好,這裡是番外篇。

拜讀了愛哥的部落格,又學到不少東西。愛哥曾經說過: 要站在巨人的丁丁上。 那麼今天,我們就站在愛哥的丁丁上來學習製作一款自訂view(開個玩笑,愛哥看到別打我)。

上一篇 帶領大家做了一款炫酷的loading動畫view手把手帶你做一個超炫酷loading成功動畫view 不知道大家跟著做了一遍沒有呢?

在開始之前,首先來說說預備知識,這些知識在愛哥的部落格上都有詳細的介紹.

如下: 應用情境很多。。比如。。。記憶體佔用百分比之類的

預備的知識有:

1.貝茲路徑 如果你不瞭解,可以來這裡進行基礎知識儲備:神奇的貝茲路徑

2.Paint.setXfermode() 以及PorterDuffXfermode

千萬不要被這個b的名字嚇到,不熟悉看到可能會認為很難記,其實 只要站在巨人的丁丁上 還是很簡單的。

好了 廢話不多說 ,跟我一步步來做一個炫酷的view吧。

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

    //繪製波紋    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
@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。

可以發現! 相交的地方消失了! 是不是很神奇。

在改一個mode 試試

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


 

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

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

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

 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 類比水波效果。

 if (x > 50) {            isLeft = true;        } else if (x < 0) {            isLeft = false;        }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會重疊
        mBitmap.eraseColor(Color.parseColor("#00000000"));        //dst         mCanvas.drawPath(mPath, mPaint);
 canvas.drawBitmap(mBitmap, 0, 0, null);        postInvalidateDelayed(10);
在最上面動態改變Y 通知重繪,現在的效果是這樣的

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

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



額。。有點海上日出的感覺(看太陽都是綠色!)

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

  //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方法
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。 效果如下:

 


最後改改字型大小 畫筆透明度。 添加個背景圖 就成了上的效果。

本項目地址:點擊開啟連結 求star

如果你覺得本部落格還可以,那麼求關注,點個頂,評個論咯。。以後還會有更多的文章等著你~

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.