編輯:關於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);
}

然後我們用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();
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);

最後改改字體大小 畫筆透明度。 添加個背景圖 就成了效果圖上的效果。
本項目地址:點擊打開鏈接 求star
如果你覺得本博客還可以,那麼求關注,點個頂,評個論咯。。以後還會有更多的文章等著你~
Android開發中使用七牛雲存儲進行圖片上傳下載,
Android開發中使用七牛雲存儲進行圖片上傳下載, Android開發中的圖片存儲本來就是比較耗時耗地的事情,而使用第三方的七牛雲,便可以很好的解決這些後顧之憂,最近
tcpdump的移植和使用方法
tcpdump的移植和使用方法簡介用簡單的話來定義tcpdump,就是:dump the traffic on a network,根據使用者的定義對網絡上的數據包進行截
Android之UI--重繪EditText以及實現Button的漸變色,ui--edittext
Android之UI--重繪EditText以及實現Button的漸變色,ui--edittext在本文中實現的是比較普遍的一個對EditText的重繪以及對於按鈕或窗口
Android 環境搭建 以及 第一個android 程序的編寫,搭建android
Android 環境搭建 以及 第一個android 程序的編寫,搭建androidAndroid 環境搭建 (1)所需材料 eclipse 、ADT 、SDK 下載地址